Using ubc in CI/CD¶
ubc is a standalone binary that exposes the full ubCode engine
on the command line.
Use it locally as part of a pre-commit hook,
in CI/CD pipelines to gate pull requests,
or on the console to explore project insights.
ubc features explorative help pages.
Add -h/--help to any command to see the available options.
Many commands directly show the help page
when executed without any options and arguments.
Some notes:
ubc checkis the canonical project linter. It resolves the whole project and reports what the editor reports — parse and markup lints, toctree and reference problems, duplicate need IDs, and schema issues, for both reStructuredText and Markdown. Pass explicit paths to scope the report to them (the whole project is still resolved),--per-filefor a fast, project-free per-file check, or--output-format jsonfor machine-readable output. See Linting on the command line for the full command model.ubc build indexruns the same indexing over the whole project, reporting the same diagnostics through the same exit policy, while also building and caching the project index just like ubCode. Therefore it makes sense to keep ubCode andubcversions in sync.ubc build htmlrenders the static site and applies the same exit policy to what it finds — both its render-phasebuild.*warnings and the index diagnostics. See Building for production.
A GitHub Actions job¶
The quality bar lives in ubproject.toml, so the workflow itself stays trivial:
# ubproject.toml
[build.html]
deny = "warning"
name: docs
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Install the `ubc` binary however you distribute it, then:
- name: Build the site
run: ubc build html
# The site is written BEFORE the quality gate decides the exit code,
# so `if: always()` uploads it even when the build came back red —
# which is exactly when you want to look at it.
- name: Upload the site
if: always()
uses: actions/upload-artifact@v4
with:
name: site
path: _build/html
Reproduce or bypass the bar for a single run with --deny
(ubc build html --deny none to build regardless,
--deny error to accept warnings),
and silence individual findings under Linting rather than
lowering the bar for the whole project.
When to Use¶
Running linting or formatting on files with
ubc checkorubc formatBuilding project indexes, needs, or reference targets
Managing ubcode project configuration, licenses, or schemas
Diffing needs between project versions or git refs
Scaffolding new ubcode projects with
ubc quickstart
Examples¶
# Lint all files in the current directory
ubc check .
# Format files, failing if any would change (CI mode)
ubc format --check .
# Build the needs index as JSON
ubc build needs . -f json -o needs.json
# Show resolved configuration
ubc config . --indent 2
# Diff needs between two git refs
ubc diff git main feature-branch
Global Options¶
Options:
--version(BOOL) — Show the version and exit
Commands¶
ubc completions¶
Generate shell completions
Arguments:
shell(CHOICE(bash, elvish, fish, powershell, zsh)) — The shell to generate completions for. If not provided, the shell will be guessed from the environment
ubc check¶
Lint a ubcode project.
With no paths, checks the whole project discovered from the current directory. With paths, the whole project is still resolved so cross-file diagnostics are correct, but only diagnostics under the given paths are reported. Pass --per-file for the previous per-file, project-free behaviour
Arguments:
files(PATH) — Files or directories to check
Options:
--per-file(BOOL) — Check each named file in isolation, without project resolution--output-format(CHOICE(human, json)) — Output format for the findings Default:human.-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--extend-ignore(TEXT) — Comma-separated list of additional diagnostic codes to ignore--isolated(BOOL) — Do not read any configuration files, use only the default configuration--config-file(PATH) — The path to a specific configuration file to use for all files--deny(CHOICE(none, info, warning, error)) — Fail if any finding at or above this level is found--max-warnings(INT) — Fail if the number of warning-level diagnostics exceeds this count--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--cache, --no-cache(BOOL) — Use on-disk cache reads
ubc format¶
Run formatting on individual files or directories.
Each file will be processed against its nearest configuration file, or the default configuration if no configuration file is found
Arguments:
files(PATH) (required) — Files or directories to run formatting on
Options:
--check, --no-check(BOOL) — Avoid writing any formatted files back; instead, exit with a non-zero status code if any files would have been modified, and zero otherwise--isolated, --no-isolated(BOOL) — Do not read any configuration files, use only the default configuration--config-file(PATH) — The path to a specific configuration file to use for all files-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--preview, --no-preview(BOOL) — Activate this command in preview mode
ubc clean¶
Clear any caches in the directory and any subdirectories
Arguments:
path(PATH) — The path to the directory to clean (defaults to the current directory)
ubc config¶
Show the nearest configuration in JSON format, resolving any extends and defaults
Arguments:
path(PATH) — The path to start the config search from (defaults to the current directory)
Options:
-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.-i, --indent(INT) — Number of spaces to indent JSON Default:0.--default, --no-default(BOOL) — Show the default configuration instead--schema, --no-schema(BOOL) — Show the configuration schema instead--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc script¶
Run a script defined in ubproject.toml
Arguments:
key(TEXT) (required) — The script key to execute
Options:
--path(PATH) — The path to the project root (defaults to the current directory)-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc quickstart¶
Create an example ubcode project
Arguments:
path(PATH) — The path to write to (defaults to the current directory)
Options:
-o, --overwrite(BOOL) — Overwrite existing files-f, --flavor(CHOICE(minimal, full, markdown, variants)) — The project flavor to scaffold Default:minimal.
ubc agent-skill¶
Generate a SKILLS.md describing all CLI commands for AI agents.
Introspects the full CLI tree and produces a Markdown reference listing every command, sub-command, argument, and option together with the ubc version that generated the document
Options:
-o, --output(PATH) — Path to write the SKILLS.md file. If omitted, prints to stdout--sort-commands, --no-sort-commands(BOOL) — Whether to sort commands alphabetically (default to order in help)
ubc build¶
Commands for building projects
ubc build list-documents¶
Print out a list of the documents that would be indexed for this project
Arguments:
path(PATH) — The path to the project root (defaults to the current directory)
Options:
--codelinks, --no-codelinks(BOOL) — Also list files for codelinks projects--codelinks-project(TEXT) — Only list files for a specific codelinks project (implies--codelinks)--source-documents, --no-source-documents(BOOL) — List the source documents (RST/MD files)--parser(BOOL) — Print the parser name alongside each source document--order(CHOICE(toctree, path)) — Order of the listed source documents.toctree(the default) lists documents reachable from the root toctree in depth-first toctree order, then all remaining documents sorted by path;pathsorts every document by path (and skips the index pipeline entirely) Default:toctree.--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc build index¶
Index the project and report its diagnostics.
Findings are summarised by severity; by default any warning-or-worse finding yields a non-zero exit, tunable with --deny / --max-warnings. Pass --show-warnings to print the per-finding detail
Arguments:
path(PATH) — The path to the project root (defaults to the current directory)
Options:
-w, --show-warnings(BOOL) — Print the detail of each finding (otherwise only the summary count is shown)-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--lint-extend-ignore(TEXT) — Comma-separated list of additional diagnostic codes to ignore--deny(CHOICE(none, info, warning, error)) — Fail if any finding at or above this level is found--max-warnings(INT) — Fail if the number of warning-level diagnostics exceeds this count--cache, --no-cache(BOOL) — Use on-disk cache reads--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc build needs¶
Build the needs index and output to a file
Arguments:
path(PATH) — The path to the project root (defaults to the current directory)
Options:
-f, --format(CHOICE(json, parquet)) — The output format Default:json.-o, --outpath(PATH) — The path to the output file--source-maps, --no-source-maps(BOOL) — Include source map information for each need--content, --no-content(BOOL) — Include the content field for each need--pretty, --no-pretty(BOOL) — Pretty print the JSON output-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--cache, --no-cache(BOOL) — Use on-disk cache reads--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc build validate-json¶
Validate a needs.json file
Arguments:
path(PATH) (required) — The path to the needs.json fileids(TEXT) — Only validate certain need IDs
Options:
-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc build targets¶
Build the reference targets index and output to a file (experimental)
Arguments:
path(PATH) — The path to the project root (defaults to the current directory)
Options:
-f, --format(CHOICE(inv)) — The output format Default:inv.-o, --outpath(PATH) — The path to the output file--compress, --no-compress(BOOL) — Whether to compress the inv file with zlib-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--cache, --no-cache(BOOL) — Use on-disk cache reads--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc build html¶
Build a static HTML site for the project (alpha).
The command works today and is under active development. It is in alpha: the emitted markup, the theming surface and the available options may still change between releases, so it is not yet recommended for production builds. Configuration lives under [build.html] in ubproject.toml.
The site is written first and then judged: the default bar is --deny warning, so any warning-or-worse finding — render-phase build warnings and indexing diagnostics alike — yields a non-zero exit. Move the bar with [build.html] deny in ubproject.toml, or with --deny / --max-warnings for one run
Arguments:
path(PATH) — The path to the project root (defaults to the current directory)
Options:
-o, --output(PATH) — The output directory for the built site-w, --show-warnings(BOOL) — Print the detail of each build and indexing warning--fresh(BOOL) — Re-render every page, ignoring any existing build manifest--strict-sources(BOOL) — Fail if a source file changes during the build (the index/render window), instead of re-indexing and retrying once-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--lint-extend-ignore(TEXT) — Comma-separated list of additional diagnostic codes to ignore--deny(CHOICE(none, info, warning, error)) — Fail if any finding at or above this level is found--max-warnings(INT) — Fail if the number of warning-level diagnostics exceeds this count--cache, --no-cache(BOOL) — Use on-disk cache reads--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc build linkcheck¶
Check the project’s external links (alpha).
Every external URL the project references is requested once — however many times it is written — and every OCCURRENCE of a bad one is reported, so a dead link used in twelve files is twelve locations to fix rather than one.
Verdicts are richer than pass/fail: a 403 that a bot-blocker returned, somebody else’s 5xx outage and a permanent redirect are each their own class with their own severity. The default bar is --deny error, so only a VERIFIED-dead link fails the command; move it with [linkcheck] deny in ubproject.toml, or with --deny / --max-warnings for one run.
Results are cached per project under .ub_cache/linkcheck/, so a second run over an unchanged project makes no network requests at all. Failures are never cached, so a link that has been fixed is noticed immediately. Configuration lives under [linkcheck] in ubproject.toml
Arguments:
path(PATH) — The path to the project root (defaults to the current directory)
Options:
-w, --show-links(BOOL) — Print every occurrence of every finding (otherwise only the summary is shown for a passing run)--output-format(CHOICE(human, json, sarif)) — Output format for the findings Default:human.--fix-redirects(BOOL) — Rewrite permanently-redirected URLs in the source that wrote them--dry-run(BOOL) — Print what--fix-redirectswould change, and write nothing--refresh(BOOL) — Re-check every link, ignoring stored results--offline(BOOL) — Never touch the network: serve stored results and report anything else as unchecked-c, --config(TEXT) — Configuration override (repeatable). Example: ‘linkcheck.workers = 4’ Env:UBCODE_CONFIG_OVERRIDE.--lint-extend-ignore(TEXT) — Comma-separated list of additional diagnostic codes to ignore--deny(CHOICE(none, info, warning, error)) — Fail if any finding at or above this level is found--max-warnings(INT) — Fail if the number of warning-level diagnostics exceeds this count--cache, --no-cache(BOOL) — Use on-disk cache reads--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc build linkcheck cache¶
Manage the stored link-check results
ubc build linkcheck cache dir¶
Print the project’s link-check result cache directory
Options:
--path(PATH) — The path to the project root (defaults to the current directory)
ubc build linkcheck cache list¶
List stored results (URL, verdict and age), in URL order
Options:
--path(PATH) — The path to the project root (defaults to the current directory)
ubc build linkcheck cache clean¶
Remove one stored result (by URL) or the whole cache
Arguments:
url(TEXT) — The URL to forget; omit to clear the whole cache
Options:
--path(PATH) — The path to the project root (defaults to the current directory)
ubc license¶
Commands for managing licenses
ubc license show¶
Show information for the current license
Options:
-k, --key(TEXT) — The license key to show information for, otherwise look in configuration Env:UBCODE_LICENSE_KEY.-u, --user(TEXT) — The user identifier for user-based licenses Env:UBCODE_LICENSE_USER.--dev, --no-dev(BOOL) — Use the development product--json, --no-json(BOOL) — Print output as JSON. Implies –quiet--show-activated, --no-show-activated(BOOL) — Show activated machines-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc license hash¶
Show hash for a given user e-mail
Options:
-u, --user(TEXT) — User e-mail to hash. If not provided, look in configuration Env:UBCODE_LICENSE_USER.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc license activate¶
Activate the current license
Options:
-k, --key(TEXT) — The license key to activate, otherwise look in configuration Env:UBCODE_LICENSE_KEY.-u, --user(TEXT) — The license user to activate, otherwise look in configuration Env:UBCODE_LICENSE_USER.--dev, --no-dev(BOOL) — Use the development product-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc license config-file¶
Show the path to the license configuration file
ubc license clean¶
Clear the ublicense cache.
This is useful to refresh the license activation before going offline for a while
ubc schema¶
Commands for ontology schema validation
ubc schema validate¶
Validate needs against the ontology schema
Arguments:
path(PATH) — The path to the project root (defaults to the current directory)
Options:
-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--cache, --no-cache(BOOL) — Use on-disk cache reads--show-warnings(BOOL) — Show all build warnings/diagnostics alongside validation results--lint-extend-ignore(TEXT) — Comma-separated list of additional diagnostic codes to ignore--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc query¶
Query a ubcode project: its needs graph, and what it can cross-reference
ubc query filter¶
Filter and display needs using a Python-like expression
Arguments:
filter_expr(TEXT) — Python-like filter expression, e.g.type == "req" and status == "open"
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--field(TEXT) — Field to include in output (repeatable). Defaults to id, type, title-f, --format(CHOICE(table, json)) — Output format Default:table.--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc query cypher¶
Run a read-only openCypher query over the needs graph.
Nodes are needs, labelled by their type (e.g. (:requirement)).
Relationships are typed links, typed by the link option name (e.g. -[:links]->).
Properties are a need’s fields plus the built-ins id, type, and content.
The engine is read-only: write clauses (CREATE/MERGE/SET/DELETE) are rejected.
A filter-style query projects a single node column, e.g. MATCH (n:requirement) WHERE n.status = 'open' RETURN n.
Multi-column and aggregation projections are allowed for tabular output, e.g. MATCH (n) RETURN n.type, count(*).
Pass --schema (instead of a query) to print the graph’s schema: node labels (need types), relationship types (link options), and node properties with their data types.
A query that references a label, relationship type, or property absent from the whole project prints a warning to stderr (with a did-you-mean suggestion); pass --strict to treat such warnings as an error instead of running the query.
See https://ubcode.useblocks.com/usage/ubquery.html for the query language reference
Arguments:
query(TEXT) — Read-only Cypher query, e.g.MATCH (n:req)-[:links]->(m) RETURN n.id, m.id
Options:
--schema(BOOL) — Print the needs graph schema (node labels, relationship types, and node properties with their data types) instead of running a query. Conflicts with providing a QUERY--strict(BOOL) — Treat vocabulary warnings (an unknown label, relationship type, or property) as an error: list them and exit with code 1 instead of running the query. Distinct from the exit code 2 a malformed query or a config/license error returns-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)-f, --format(CHOICE(table, json)) — Output format Default:table.--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc query search¶
Search everything this project can cross-reference, ranked, each hit carrying the exact reStructuredText to paste.
Covered targets: the project’s own standard-domain targets (std:label targets, std:term glossary entries, std:doc documents), its filed index entries (.. index::, the :index: role and glossary terms, as index:entry), and every entry of every loaded intersphinx inventory (py:function, rst:directive, …).
This searches reference TARGETS and filed index entries, not document CONTENT: it answers “what can I reference, how do I spell it, and is this phrase already indexed?”. An index:entry hit carries no snippet, because no role resolves to an index entry — its kind and location are the answer.
Matching is AND-matched keyword search, so pass a few specific keywords or the exact name, not a sentence. The exact name ranks first, a partial name completes by prefix (numpy.ad finds numpy.add), -word excludes, and a quoted phrase requires all its words.
Pass NO query (or an empty one) to LIST every reference instead, ordered by name — with --kind label, that is “list this project’s labels”.
Filters: --kind takes a domain:objtype glob (py:*, *:label) or one of the shorthands label, term, doc, index; a kind that matches nothing is an empty result, not an error, because a project’s object types are open-ended. --scope takes local, external, or one configured intersphinx project name, and a value outside that closed set is an error listing the accepted ones.
Exit codes: 0 when at least one reference was found, 1 when none was (a reportable condition, as in ubc diff), and 2 for a usage, configuration, license or unknown---scope error.
The reference index is built per invocation, so this is for interactive and CI use; the repeated-query workload has its daemons (ubc serve lsp, ubc serve mcp)
Arguments:
query(TEXT) — Keywords or an exact name. Omit (or pass an empty string) to list every reference, ordered by name
Options:
--kind(TEXT) — Restrict to one object type: adomain:objtypeglob (std:label,py:*,*:label) or one of the shorthandslabel,term,doc,index--scope(TEXT) — Restrict by where a reference is defined:local,external, or one configured intersphinx project name--limit(INT) — Maximum number of hits to return (1-50) Default:20.-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)-f, --format(CHOICE(table, json)) — Output format Default:table.--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc intersphinx¶
Inspect Sphinx objects.inv inventories and manage the intersphinx cache
ubc intersphinx inspect¶
Inspect a Sphinx objects.inv inventory (a local file or a URL)
Arguments:
input(TEXT) (required) — Path or URL to anobjects.invinventory file
Options:
-f, --format(CHOICE(sphinx, json)) — Output format Default:sphinx.-d, --domain(TEXT) — Filter by domain name (*= wildcard)-o, --object-type(TEXT) — Filter by object type (*= wildcard)-n, --name(TEXT) — Filter by reference name (*= wildcard)--refresh(BOOL) — Force revalidation of a cached URL even if it is still fresh--offline(BOOL) — Never fetch: serve a cached copy of a URL, or fail if none exists
ubc intersphinx diff¶
Compare two Sphinx objects.inv inventories (local files or URLs)
Exits 0 when they are identical, 1 when they differ, and 2 when an inventory could not be read or parsed (or the report could not be written). The comparison is key-based on (domain:type, name), so row order is not a difference
Arguments:
a(TEXT) (required) — Path or URL to the FIRST inventory (the baseline)b(TEXT) (required) — Path or URL to the SECOND inventory (the one being compared)
Options:
-f, --format(CHOICE(table, json)) — Output format Default:table.-d, --domain(TEXT) — Filter by domain name (*= wildcard). Applied to BOTH inventories before comparing, so a filtered diff answers “are these equal within this scope?”-o, --object-type(TEXT) — Filter by object type (*= wildcard). Applied to both inventories-n, --name(TEXT) — Filter by reference name (*= wildcard). Applied to both inventories--refresh(BOOL) — Force revalidation of a cached URL even if it is still fresh--offline(BOOL) — Never fetch: serve cached copies of URLs, or fail if none exist--exit-zero(BOOL) — Exit 0 even when differences are found (report-only mode), instead of the exit code 1 that “the inventories differ” otherwise returns. The report is unchanged; only the process status is. Does NOT mask the exit code 2 an unreadable or unparseable inventory returns — that means no comparison happened at all
ubc intersphinx list¶
List the references of every intersphinx project configured for the current ubcode project
Arguments:
projects(TEXT) — Limit the output to the named configured intersphinx project(s), i.e. the[intersphinx.projects.<name>]keys. Repeatable; omit to list every configured project
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)-f, --format(CHOICE(sphinx, json)) — Output format Default:sphinx.-d, --domain(TEXT) — Filter by domain name (*= wildcard)-o, --object-type(TEXT) — Filter by object type (*= wildcard)-n, --name(TEXT) — Filter by reference name (*= wildcard)--refresh(BOOL) — Force revalidation of every cached inventory URL, even if still fresh--offline(BOOL) — Never fetch: serve cached copies of URL locations, or report a miss-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.
ubc intersphinx cache¶
Inspect and manage the central inventory cache
ubc intersphinx cache dir¶
Print the central inventory cache directory
ubc intersphinx cache list¶
List cached inventories (URL, size, and age), in stable order
ubc intersphinx cache clean¶
Remove one cached inventory (by URL) or the whole cache bucket
Arguments:
url(TEXT) — The inventory URL to remove; omit to clear the entire cache bucket
ubc report¶
Render a report template against the project’s needs index
Arguments:
template_name(TEXT) — Name of the .html.j2 template to render, looked up under the project’s reports directory ([reports].directory in ubproject.toml). Omit if using –list
Options:
--list(BOOL) — List the available .html.j2 templates instead of rendering-o, --outpath(PATH) — Path to write the rendered HTML to. Defaults to ‘/_build/ .html’ -p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--cache, --no-cache(BOOL) — Use on-disk cache reads--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc diff¶
Diff & impact analysis for local projects and needs.json
Options:
-n, --needs(PATH) — Needs.json file path (can be used twice for comparison)-p, --project(PATH) — Project path (can be used twice for comparison)-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--impact(BOOL) — Enable impact analysis--impact-depth(INT) — Set impact analysis link depth Default:1.--impact-direction(CHOICE(outgoing, incoming, both)) — Set impact analysis direction Default:both.--impact-max-chains(INT) — Maximum number of impact chains per changed need (0 = unlimited) Default:20.--allow-type(TEXT) — Allow-filter for need types (repeatable)--deny-type(TEXT) — Deny-filter for need types (repeatable)--allow-core(TEXT) — Allow-filter for core fields (repeatable)--deny-core(TEXT) — Deny-filter for core fields (repeatable)--allow-extra(TEXT) — Allow-filter for extra fields (repeatable)--deny-extra(TEXT) — Deny-filter for extra fields (repeatable)--allow-link(TEXT) — Allow-filter for link types (repeatable)--deny-link(TEXT) — Deny-filter for link types (repeatable)--deny-externals(BOOL) — Deny-filter external needs-f, --format(CHOICE(html, console)) — Output format Default:console.-o, --outpath(PATH) — Output file path (for HTML format)--html-theme(CHOICE(dark, light, auto)) — HTML theme for output Default:auto.--cache, --no-cache(BOOL) — Use on-disk cache reads-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.
ubc diff git¶
Git-based diff and impact analysis
Arguments:
ref1(TEXT) — First git reference (branch/tag/commit)ref2(TEXT) — Second git reference (branch/tag/commit)
Options:
-p, --project(PATH) — Project path. Defaults to the current working directory-n, --needs(PATH) — Needs.json file path in the repository--staged(BOOL) — Compare the staging area with HEAD--impact(BOOL) — Enable impact analysis--impact-depth(INT) — Set impact analysis link depth Default:1.--impact-direction(CHOICE(outgoing, incoming, both)) — Set impact analysis direction Default:both.--impact-max-chains(INT) — Maximum number of impact chains per changed need (0 = unlimited) Default:20.--allow-type(TEXT) — Allow-filter for need types (repeatable)--deny-type(TEXT) — Deny-filter for need types (repeatable)--allow-core(TEXT) — Allow-filter for core fields (repeatable)--deny-core(TEXT) — Deny-filter for core fields (repeatable)--allow-extra(TEXT) — Allow-filter for extra fields (repeatable)--deny-extra(TEXT) — Deny-filter for extra fields (repeatable)--allow-link(TEXT) — Allow-filter for link types (repeatable)--deny-link(TEXT) — Deny-filter for link types (repeatable)--deny-externals(BOOL) — Deny-filter external needs-f, --format(CHOICE(html, console)) — Output format Default:console.-o, --outpath(PATH) — Output file path (for HTML format)--html-theme(CHOICE(dark, light, auto)) — HTML theme for output Default:auto.--cache, --no-cache(BOOL) — Use on-disk cache reads-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.
ubc serve¶
Run a ubcode server
ubc serve mcp¶
Run the Model Context Protocol (MCP) server over stdio
Options:
--default-config(PATH) — Path to the default ubproject.toml configuration file-c, --config(TEXT) — Configuration override (repeatable). Example:lint.ignore = ["W001"]--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.
ubc serve lsp¶
Run the language server over stdio (or TCP with --port)
Options:
-p, --port(INT) — Start a TCP instance of the language server listening on the given port--log-to-output(CHOICE(always, debug, info, warning, error, off)) — When to log to the output channel Default:info.--show-notifications(CHOICE(always, debug, info, warning, error, off)) — When to show notifications Default:error.-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’
ubc agent¶
Spec-driven V-model engine for AI authoring agents: workflow heartbeat, gap and impact analysis, release gating, and config-driven stage authoring (alpha).
The command works today and is under active development. It is in alpha: the subcommand set, the options and the JSON output shapes may still change between releases. Configuration lives under [agent] in ubproject.toml
ubc agent next¶
Report the next actionable workflow stage (0 or 1) as JSON. Drives the ACTIVE STREAM — the entry-root and V-subtree derived from git diff (a dirty tree infers from the NEED files changed in its working tree, staged, unstaged, or untracked but not gitignored, and only a FULLY clean tree falls back to the branch’s changes since the merge-base), or the stream anchored on --id — not the whole graph. Pre-existing gaps in other streams are surfaced as non-blocking open_streams. A report, not a gate. It exits 0 on a readable graph, except a misused --id or --stage, which reports ok false with reason id_not_found or stage_not_found and exits non-zero, so a typo is never mistaken for progress. next only REPORTS. To execute the recommended stage through the runner use ubc agent run
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the Python reference’s--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--id(TEXT) — Stateless stream anchor fornext: a NEED id (not a stage or feature name) whose stream to select, bypassing thegit diffquery. Use it when the changed NEED files cannot seed a stream (a dirty tree infers from the working tree alone, and only a FULLY clean tree falls back to the branch’s changes since the merge-base), or to focus one of several in-flight streams. Supplying--idpersists nothing: a later no-arg call again derives the stream fromgit diff. An--idthat is not a need exits non-zero. (No--feature, no state file.)--stage(TEXT) — Brief an EXPLICIT stage instead of the computed recommendation: the stage id (from[workflow]) whose route, author skill and gates to brief. Used to drive a specific ready stage the cockpit Flow strip offered (e.g. a globalrisks/decisionsstage). Still anchored on--idfor feature/context resolution. An unknown stage exits non-zero
ubc agent run¶
EXECUTE the recommended workflow stage through the configured AI runner ([agent.runner] / UBC_AGENT_RUNNER), then re-build and report what was produced plus the advanced next / gaps. Assembles a prompt from the recommended skill (or --skill <NAME> for a targeted intent such as the change-request cascade), the anchor need’s context --no-code briefing, and the resolved authoring route. The produced artefact is left UNCOMMITTED for human or UI approval. Drives the SAME active stream next reports (anchored on --id, else the git diff stream). A stage that declares no produces type and does not resolve as a code stage has no artefact to run for: that exits non-zero naming the stage, and spawns nothing
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the Python reference’s--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--id(TEXT) — Stateless stream anchor: a NEED id (not a stage or feature name) the run briefs from and drives the stream of. Without it the stream is inferred from changed NEED files: on a dirty tree from the files changed in your working tree (staged, unstaged, or untracked but not gitignored), and only on a FULLY clean tree from the branch’s changes since the merge-base. A dirty tree whose changes include no need file infers nothing, so pass--idthen, for example right after a review when only verdict files changed. And when your working tree carries changes from several streams they merge into one, so--idpicks which one to drive. The anchor need the prompt briefs from is--idwhen given, else the stream’s first entry root. An--idthat is not a need exits non-zero--skill(TEXT) — Run a NAMED skill on the anchor instead of the stage-recommended one. The assembled prompt carries<NAME>’s skill content (the installed.claude/skills/<NAME>/SKILL.md, or the profile asset when not installed) in place of the stage’sauthor_skill, while the anchor’scontext --no-codebriefing and the resolved route are unchanged. This is the execution surface for any targeted intent (e.g.change-request) without adding a verb — intents ARE skills. Without--skill,runexecutes the stage-recommended skill
ubc agent prompt¶
Print the resolved instruction for the next workflow action as PLAIN TEXT: what ubc agent run would drive next, emitted on stdout instead of executed. An instruction is led by a === WORKING DIRECTORY === header naming the project root (run spawns its runner IN that directory, a reader of the printed text does not). The no-action arms carry no header, only their NO ACTION (<reason>) line. Not a byte-preview of what run pipes: an authoring instruction defers here to the author skill’s propose-first section, because a reader has a user to ask, while run keeps the unconditional order for a headless runner. Drives the SAME active stream next reports (anchored on --id, else the git diff stream) and resolves the SAME arm: an AUTHOR instruction for a ready need-producing or code stage, a REVIEW instruction for a review-held stage, a FIX instruction when every review target already failed. When no stage is actionable it prints the one action for that state (empty / done / blocked) and still exits 0. --stage <STAGE_ID> briefs an EXPLICIT stage instead of the computed recommendation (e.g. a global risks/decisions stage the cockpit Flow strip offered). A named stage that reads blocked for the active stream is reported instead of briefed, so the text can never order authoring past a layer the stage is itself blocked on. A named stage that reads done IS briefed, led by a line naming that state so the order is not read as the first artefact. A named CODE stage (one that authors no need and gates a type through require_code) is briefed only while a need of that gated type exists for it to implement, and reported otherwise. Executes nothing, writes nothing, and resolves no runner, so it needs no [agent.runner]. Exits non-zero when --id is not a need, when --stage names a stage absent from [workflow], or when a stage is actionable but no anchor need resolves from a graph that HAS needs (a clean tree with no --id). A graph with NO needs at all is briefed from its first stage instead, and exits 0
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the Python reference’s--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--id(TEXT) — Stateless stream anchor: a NEED id (not a stage or feature name) the instruction briefs from and drives the stream of. Without it the stream is inferred from changed NEED files: on a dirty tree from the files changed in your working tree (staged, unstaged, or untracked but not gitignored), and only on a FULLY clean tree from the branch’s changes since the merge-base. A dirty tree whose changes include no need file infers nothing, so pass--idthen, for example right after a review when only verdict files changed. And when your working tree carries changes from several streams they merge into one, so--idpicks which one to drive. The anchor need the instruction briefs from is--idwhen given, else the stream’s first entry root. An--idthat is not a need exits non-zero--stage(TEXT) — Brief an EXPLICIT stage instead of the computed recommendation: the stage id (from[workflow]) whose route, author skill and gates to brief. Used to drive a specific ready stage the cockpit Flow strip offered (e.g. a globalrisks/decisionsstage). Still anchored on--idfor feature/context resolution. An unknown stage exits non-zero, naming the stage it rejected. A KNOWN stage whose own dependency is not met yet readsblockedfor the active stream, and that prints a report instead of an authoring order, so it never tells you to author past a layer the stage is itself blocked on. A stage that readsdonefor that stream is still briefed, led by a line naming the state, and for a need-producing stage that line says the artefact it orders is an additional one. A stage that still carries a gap or an unfinished review readsreadyand is briefed with no such line. A CODE stage (it authors no need, it implements arequire_codetype in source) is briefed only while a need of that type exists for it to implement, and reported otherwise
ubc agent status¶
Report per-stage workflow state as JSON (the heartbeat): one row per stage with its state (done / ready / blocked), coverage counts, failing gates, and route. A report, not a gate — always exits 0 on a readable graph
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the Python reference’s--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent gaps¶
Report the full structural gap list as JSON ({gaps, by_category, summary, ok}). Exits non-zero when any gap is found — the whole-graph gate used to capture and read a release-check baseline. --scope <NEED_ID> narrows the gate to one stream (the anchor’s entry root and its trace-subtree) and recomputes the tally, summary and exit code over that subset
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the Python reference’s--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--scope(TEXT) — Narrowgaps/traceto one stream: pass aNEED_IDand the gate keeps only the gaps of that need’s stream — its entry root and the whole trace-subtree beneath, resolved through the trace graph (NOT a path convention, so it works on any on-disk layout). The tally, summary and exit code are recomputed over that subset; an anchor that resolves to no needs is an unknown scope and fails the gate. Scope is the TRACE-CONNECTED stream grown from the anchor, not everything co-located on disk: a fully disconnected need (no links in or out) is still caught by whole-graphgaps/release-check, not this scoped gate
ubc agent trace¶
Report the bidirectional trace-coverage matrix as JSON ({ok, edges}): one row per declared trace edge with the forward and backward covered/total counts and the surviving per-direction gap ids. Exits non-zero if any edge is uncovered in either direction. A presentation of the same per-edge obligation gaps computes, never a second model
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the Python reference’s--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings--scope(TEXT) — Narrowgaps/traceto one stream: pass aNEED_IDand the gate keeps only the gaps of that need’s stream — its entry root and the whole trace-subtree beneath, resolved through the trace graph (NOT a path convention, so it works on any on-disk layout). The tally, summary and exit code are recomputed over that subset; an anchor that resolves to no needs is an unknown scope and fails the gate. Scope is the TRACE-CONNECTED stream grown from the anchor, not everything co-located on disk: a fully disconnected need (no links in or out) is still caught by whole-graphgaps/release-check, not this scoped gate
ubc agent release-check¶
Gate NEW structural gaps against a ratcheting baseline of accepted debt. A baselined gap is reported as non-blocking debt; a gap absent from the baseline fails the gate. On a passing run the baseline ratchets DOWN to the gaps that still exist, so a fixed gap can never be readmitted. --with-verdicts folds the substance gate (the verdict-check verb) into the same pass: the combined gate is ok only when both the structural gaps and the substance problems are clear
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the Python reference’s--srcdir--baseline(PATH) — Path to the accepted-gap baseline file (a JSON gap-key list). A gap in the baseline is reported as non-blocking debt; a gap absent from it fails the gate. Without--baselinethe verb gates on every gap (the whole-graph behaviour)--update-baseline(BOOL) — On a passing run, ratchet the baseline file DOWN to the gaps that still exist (drop fixed gaps so they can never be readmitted). No-op without--baseline. Read-only by default so the gate never mutates state on a reporting run--with-verdicts(BOOL) — Also run the substance (verdict) gate beside the structural gates and fold its result into the combinedok/ exit code. Reads the AI-authored review verdicts from the native.pharaoh/verdicts/directory, derives the review-required need types from the same[workflow]review stages, and surfaces the per-category substance problems (verdicts) beside the structural ones. The combined gate passes only when both the structural gaps and the substance problems are clear--verdicts-dir(PATH) — Directory of review verdict JSON files. Overrides the native<srcdir>/.pharaoh/verdictsdefault when given. Only consulted with--with-verdicts--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent verdict-check¶
Report the AI-review substance gate as JSON ({ok, missing, failing, malformed, outdated, unverifiable, stale}). Reads the AI-authored review verdicts from the native .pharaoh/verdicts/ directory and reports which review-required needs block the release: a required need with no valid verdict (missing), a need whose verdict records a failing judgment (failing), a verdict file that is itself unusable (malformed), a need whose verdict was recorded against a stale content fingerprint (outdated), a need a verdict could not be evaluated for (unverifiable), and a leftover verdict for a need absent from the graph (stale, warn-only). The required need types are derived from the [workflow] review stages, not a hard-coded list. Exits non-zero whenever missing, failing, malformed, outdated, or unverifiable is non-empty; stale never blocks
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the heartbeat verbs’--srcdir. When set, the verdict directory defaults to<srcdir>/.pharaoh/verdictsand the required types are derived from<srcdir>’s[workflow]review stages--verdicts-dir(PATH) — Directory of review verdict JSON files. Overrides the native<srcdir>/.pharaoh/verdictsdefault when given. Named--verdicts-dirto matchrelease-check --with-verdicts;--dirstays a hidden alias--require-type(TEXT) — Force a single need type that must each carry a passing verdict. When omitted, the required types are derived from the[workflow]review-skill stages--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent verdict-submit¶
Submit an evaluator-authored schema-2 verdict for ONE need id as JSON. Reads the axes (+ optional summary and the advisory agent / model provenance) from --file (- for stdin), then the ENGINE stamps schema, need, criteria, criteria_fingerprint, and reviewed_fingerprint — overwriting anything the evaluator supplied for those keys, so it cannot mis-stamp them — validates the stamped result against the need’s type’s quality policy, and on success writes .pharaoh/verdicts/<ID>.json and prints a short ack ({written, fresh}). On rejection prints a machine-readable error report naming why (unknown_need / no_quality_policy / unreadable_input / invalid_json / validation_failed, the last carrying every structural problems entry) and writes nothing. Exits non-zero on any rejection
Arguments:
need_id(TEXT) (required) — The need id the submitted verdict is for
Options:
--file(TEXT) — Path to the evaluator-authored verdict JSON, or-to read stdin--fingerprint(TEXT) — The one-hop content fingerprint the reviewer captured for this need from the review brief /next(its entry in the brief’sfingerprints). When given, arms the freshness race guard: the submit is REJECTED if the need’s content changed after it was scored, so a review can never green content the reviewer never saw. Omit it only for a deliberate manual submit--criteria-fingerprint(TEXT) — The criteria fingerprint the reviewer captured for this need’s type from the review brief /next(the brief’scriteria.fingerprint). When given, arms the criteria race guard: the submit is REJECTED if the[quality]pack changed after the need was scored, so a review can never green scores made against a stale rubric. Omit it only for a deliberate manual submit-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the heartbeat verbs’--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent review-brief¶
Report the reviewer briefing for a need TYPE or explicit ids as JSON: the review skill, the absolute verdicts directory, the review-target need ids (after excluding already-fresh ones — see fresh_skipped), each target’s current one-hop fingerprint, the produced type’s quality-pack projection (pack name, guidance, scored axes), the derived JSON Schema a submitted verdict must satisfy, and the verdict-submit invocation template. This is the SAME briefing ubc agent next attaches to a review-held stage — the shared build_review_brief builder the two verbs never duplicate or diverge on. <TYPE> selects every present need of that type; --ids selects explicit ids instead (mixed types allowed, grouped per type). --all includes already-fresh needs too. A report, not a gate: exits zero even when every candidate is fresh; exits non-zero only on a genuine selection error (an unknown id, or a type/id with no review-carrying stage)
Arguments:
need_type(TEXT) — The need TYPE to brief: every present need of that type with a review-carrying[workflow]stage. Mutually exclusive with--ids; exactly one of the two must be given
Options:
--ids(TEXT) — Explicit need ids to brief instead of a type (mixed types allowed — grouped per type internally, one entry per type inbriefs). Mutually exclusive with<TYPE>--all(BOOL) — Include already-fresh needs too, instead of excluding them via the freshness pre-filter (fresh_skippedin the output)-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the heartbeat verbs’--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent audit¶
Inspect ONE need’s trace coverage as JSON: its id, title, type, status, body, and source pointer; a trace sub-object scoping the outgoing forward and incoming _back trace links to their target ids; and a full links map of every named link present (forward and _back), including non-trace links. A READ briefing for a single id — exits non-zero when the id is absent from the built graph, never substituting another need or an empty stand-in. Takes the need id via --id <NEED_ID> or the positional <NEED_ID> (kept for back-compat). --id wins when both are given, and neither given is a clear error
Arguments:
id_positional(TEXT) — Need id to audit (e.g.REQ_AUDIT_INSPECT). The historic positional shape, kept working for back-compat. Prefer--id, the same shapenext/runaccept
Options:
--id(TEXT) — Need id to audit (e.g.REQ_AUDIT_INSPECT). Takes priority over the positionalNEED_IDwhen both are given. One of--idor the positional form is required-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the spec workflow’s--srcdir--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent context¶
Inspect ONE anchor need’s linked-need briefing as JSON: an anchor summary (id, type, title, body) plus a related list of every directly linked need, forward and _back, each carrying its own body and the relation label of the link it came in on (de-duplicated, with a count), and the same full links map audit emits. Reads the surrounding needs without opening each file; exits non-zero when the id is absent. The related_code field is an honestly-deferred capability: empty list when no code root is resolvable, but a non-zero REFUSAL when a code root DOES resolve, so a resolved-code-root project never reads a silent empty list as “this need has no related code”. The --no-code (alias --graph-only) opt-out asks for the graph briefing anyway: it returns the full briefing with related_code: null and code_omitted: true instead of refusing, so context is usable in a real code-linked project without a silent empty list. Takes the anchor need id via --id <NEED_ID> or the positional <NEED_ID> (kept for back-compat). --id wins when both are given, and neither given is a clear error
Arguments:
id_positional(TEXT) — Anchor need id (e.g.REQ_CONTEXT_INSPECT). The historic positional shape, kept working for back-compat. Prefer--id, the same shapenext/runaccept
Options:
--id(TEXT) — Anchor need id (e.g.REQ_CONTEXT_INSPECT). Takes priority over the positionalNEED_IDwhen both are given. One of--idor the positional form is required-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the spec workflow’s--srcdir--code-dir(PATH) — Code source directory forrelated_code. Supplying it makes a code root resolvable, which the verb REFUSES (exit non-zero) rather than emit a silently-emptyrelated_code: []—related_codesemantic search is deferred (DEC_RELATED_CODE_DEFERRED)--codelinks(PATH) —codelinks.tomlforrelated_code. REFUSED for the same reason as--code-dir. Even without this flag, an adjacent<srcdir>/codelinks.tomldeclaring asource_discover.src_diris auto-detected and likewise refused, so the default codelinks-bearing project never reads a silently emptyrelated_code--no-code(BOOL) — Request the graph-only briefing and OMITrelated_codeexplicitly, instead of refusing when a code root resolves. With this flagcontextreturns the full graph briefing (anchor + linked needs with bodies + links) and reportsrelated_codeasnullwithcode_omitted: true— an explicit opt-out, never a silently-emptyrelated_code: []. This makescontextusable in a real code-linked project; the deferred semantic search (DEC_RELATED_CODE_DEFERRED) is still not run. Without the flag the refuse-on-resolvable-code-root default is unchanged--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent impact¶
Report the seed-by-id BLAST RADIUS of ONE need as JSON: an anchor summary plus a reached list — the multi-hop up-and-down trace closure of every need that depends on the seed in either direction, to a --depth bound, each entry tagged with its depth and direction (up / down) and carrying its code_url / test_url (null when absent) so the code-and-test impact is visible — and a stale_gaps list holding the structural gap records already attributed to the anchor or any reached need, drawn from the same gap computation the gaps gate uses. A REPORT, not a gate: it exits zero on a present seed even with stale gaps, and exits non-zero only when the seed id is absent. Takes the seed need id via --id <NEED_ID> or the positional <NEED_ID> (kept for back-compat). --id wins when both are given, and neither given is a clear error
Arguments:
id_positional(TEXT) — Seed need id whose blast radius to report (e.g.REQ_CONTEXT_INSPECT). The historic positional shape, kept working for back-compat. Prefer--id, the same shapenext/runaccept
Options:
--id(TEXT) — Seed need id whose blast radius to report (e.g.REQ_CONTEXT_INSPECT). Takes priority over the positionalNEED_IDwhen both are given. One of--idor the positional form is required-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the spec workflow’s--srcdir--depth(INT) — Maximum hop distance from the seed the closure walk reaches. A need at the bound is reported but not expanded further. Defaults to a small bound that still crosses the V Default:4.--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent config-validate¶
Cross-check the [workflow] process config against the ubproject.toml ontology as JSON ({ok, errors, warnings}). A pure pre-flight: every type a stage produces / a trace edge or obligation names must be a declared [[needs.types]] directive, every referenced link a declared [needs.links.*] table, and every transition from/to state a declared lifecycle state — each mismatch an error. A status value absent from the states, a blank per-stage skill slot, and a declared type no stage produces are warnings. ok is the emptiness of errors; exits non-zero on any error. Reads ONLY the config — never builds the graph, loads needs.json, or runs a coverage gate — so it stays disjoint from native ubc config
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the heartbeat verbs’--srcdir-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent doctor¶
Run the config preflight as JSON ({ok, checks:[...]}): a config-driven setup health check an agent runs BEFORE driving the loop, so it fails closed on a misconfiguration before spending a run’s tokens. The first check composes the config-validate pipeline (a config-validity error is one blocking error check, its warnings are warning checks). The remaining checks are tool probes admitted ONLY when the resolved [workflow] config requires the tool: mmdc when the diagram gate is enabled with engine mermaid/both, plantuml (plus its Java runtime) when enabled with engine plantuml/both, and codelinks when a stage configures the code-trace gate. A required-but-absent tool is a blocking error carrying a remediation fix; a tool no gate requires is not probed. ok is the absence of any error-status check (warnings never flip it) and the process exits non-zero exactly when not ok. Reads ONLY the config — never builds the graph, loads needs.json, or runs a coverage gate
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the heartbeat verbs’--srcdir--config-name(TEXT) — Configuration file name to search for Default:ubproject.toml.-c, --config(TEXT) — Configuration override (repeatable). Example: ‘lint.ignore = [“W001”]’ Env:UBCODE_CONFIG_OVERRIDE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent install¶
Bootstrap a project into the agentic loop from a named profile preset. Scaffolds the [workflow] process configuration and ontology into ubproject.toml, installs the profile’s AI-asset bundle (skills, commands, agents) into the host integration directories, and records every owned file in the install manifest at .pharaoh/agent/install-manifest. --profile <name> selects the preset (default vmodel); an unknown name writes nothing and exits non-zero listing the available profiles. --detect grounds the configuration in the existing needs graph instead of the blank profile defaults and exits non-zero on a graphless project. Non-destructive by default; --overwrite clobbers existing files scoped to the managed set
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the heartbeat verbs’--srcdir--profile(TEXT) — Named profile preset to scaffold from (defaultvmodel). An unknown name writes nothing and exits non-zero listing the available profiles Default:vmodel.--detect(BOOL) — Brownfield mode: introspect the existing needs graph and ground the configuration in it instead of writing the blank profile defaults. Exits non-zero when the project has no introspectable requirement graph--plan(BOOL) — Emit the derived workflow plan as JSON and write nothing (use with –detect)--answers(PATH) — JSON map of open-question id → chosen value, applied to the derived workflow (use with –detect)--from-needs-json(PATH) — Derive the workflow from a prebuilt needs.json instead of indexing (use with –detect)--overwrite(BOOL) — Clobber existing destination files instead of skipping them, scoped to the set this command scaffolds. Non-destructive by default--register-mcp(TEXT) — Register the ubCode MCP server with a terminal harness after installing (e.g. claude-code-cli)--cache, --no-cache(BOOL) — Use on-disk cache reads-c, --config(TEXT) — Configuration override (repeatable), used only by--detect--config-name(TEXT) — Configuration file name to search for (used only by--detect) Default:ubproject.toml.--license-key(TEXT) — Use a specific license key Env:UBCODE_LICENSE_KEY.--license-user(TEXT) — Use a specific license user Env:UBCODE_LICENSE_USER.--license-stage(CHOICE(prod, dev)) — Use a specific license stage Env:UBCODE_LICENSE_STAGE.-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings
ubc agent update¶
Reconcile a previously installed project against the current preset, touching only the files the manifest records as install-owned. For each owned file it performs a three-way comparison between the preset’s current content, the recorded baseline, and the on-disk content: an unedited file is updated to the preset content, a locally edited file is PRESERVED and reported as a conflict (never blind-clobbered) unless --overwrite resolves it preset-wins. Refreshes the manifest afterwards. Exits non-zero when a conflict was not resolved by --overwrite, with the conflicts accompanying the exit
Options:
-p, --project(PATH) — Path to the project root or any file within it (defaults to cwd)--srcdir(PATH) — Alias for--project, matching the heartbeat verbs’--srcdir--overwrite(BOOL) — Resolve conflicts in favour of the preset (preset-wins) for the manifest-owned set only, instead of preserving a locally edited owned file and reporting it as a conflict-v, --verbose(BOOL) — Show debug information-q, --quiet(BOOL) — Only show errors and warnings