CLI compatibility and option policy
lidarslam-map is the supported product command. This page defines which
parts of its command line are intended to remain compatible through v1 and
how provisional and deprecated options are moved without surprising existing
users.
The machine-readable inventory is
contracts/cli-v1.json.
It records not only option names and visibility, but also every value-taking
option's type, metavar, bounded choices, default behavior, units and numeric
constraints. The contract also describes positional-directory contents.
Product surface
On a terminal with interactive stdin and stdout, invoking lidarslam-map
without a command opens a small home that routes to the existing demo,
start, sessions, or read-only doctor workflow. It prints the delegated
command before it can run and requires an explicit yes before demo download
or writes. Doctor needs no confirmation because it uses no network and writes
no files. This is a choice-reducing front door, not a new command contract. In
non-interactive use, no arguments remain a usage error printed to stderr with
exit code 2, so an existing script never starts prompting after an upgrade.
The beginner workflow is one orchestration command:
lidarslam-map start <rosbag2_dir>
Automation retains the three explicit lifecycle commands:
lidarslam-map doctor [rosbag2_dir]
lidarslam-map run <rosbag2_dir> --output-dir <dir>
lidarslam-map inspect <output_dir>
Omitting rosbag2_dir checks product runtime files, prefix activation,
Humble/Jazzy, the ROS CLI and bag reader, and fixed-demo storage. Providing the
directory preserves the existing bag compatibility preflight. The system JSON
report is governed by system-doctor-v1.schema.json and omits local paths. A
storage rejection includes exact additional_bytes_required, a rounded-up
human shortage, and the placeholder-free retry command. Multiple system
findings retain their individual recovery text, while top-level next_action
and the human Do this now card select exactly one dependency-ordered first
recovery; rerunning doctor reprioritizes the remaining findings. Bag preflight
v6 checks bounded recorded Odometry parent/child frames against the bag's
dynamic TF graph, then reports replay-order startup and future-TF gaps for the
selected PointCloud2 topic. It does not claim that a transform will be fresh or
interpolatable at live runtime.
The full bag preflight retains its path and local commands for local automation.
Use doctor <rosbag2_dir> --public-json for a reviewed public issue; its
public-doctor-evidence-v1 projection keeps only type/count/check/profile and
stable finding-code evidence and returns path-free input-error JSON as well.
The human bag report always ends with that shell-safe command for the exact
input and warns that the full report must remain local. Through the product
CLI, a ready report exposes one exact-input lidarslam-map start action and
hides lower-level launch alternatives. A report with findings withholds that
start action and instead prints the exact doctor retry after the first
finding is resolved. Direct use of the preflight script retains its detailed
developer commands.
The default product card is bounded to status, bag duration and message count,
input types without topic/frame names, selected profile, four check statuses,
the first finding plus remaining stable codes, and one action. It prints an
exact private doctor ... --json command for full local reasons and commands;
that JSON must not be shared. The compact card and detailed JSON are both
read-only and make no network request.
Viewing is an optional post-processing command, not another required mapping step:
lidarslam-map view <output_dir> [--viewer autoware|foxglove]
Returning to local work and comparing two retained sessions are stable, non-mutating commands:
lidarslam-map sessions [sessions_root]
lidarslam-map compare <left_session> <right_session>
Non-destructive edit and multi-session merge are also optional
post-processing commands. They publish new verified outputs and never mutate
the completed maps supplied as inputs.
Research scripts, benchmark runners, ROS launch arguments, and the historical
ros2 run lidarslam lidarslam node are outside this CLI contract.
The checkout/release-bundle Docker host launcher is delivery tooling around the
same start workflow, not an additional installed CLI command. Its additive
--json option is accepted only with --dry-run and emits the versioned
docker-map-bag-plan-v1 plan to stdout without Docker, network, or filesystem
writes. Because that plan includes local paths, wrappers should keep it local
and should not paste raw output into issue reports.
Stability labels
| Label | Promise |
|---|---|
| Stable | The name, accepted value shape, and meaning are v1 compatibility commitments. Additive choices are allowed when they do not change an existing invocation. |
| Provisional | The option works and is tested, but its location or spelling may change before v1. A replacement and compatibility alias must land before removal. |
| Deprecated | A documented replacement exists. The old spelling continues to work during its compatibility window and emits an actionable warning when exercised. |
During v0.9, a stable option cannot be silently renamed, removed, or assigned a different default meaning. If a security or data-integrity defect requires a behavior change, the release notes and command output must identify it.
After v1.0, removal of a stable option requires a major release. A deprecated spelling must continue to work for at least one minor release, emit one actionable warning to stderr, and preserve its previous exit-code behavior. Automation must not parse warnings from stdout.
No current deprecated option has a scheduled removal release. The
machine-readable policy records removal_status: not_scheduled; choosing a
release later requires a reviewed contract and migration-guide change, not
only a parser edit.
JSON artifact compatibility is governed by the published JSON schemas, not by this option policy or the repository version.
Current inventory
| Command | Routine stable options | Advanced stable options | Deprecated options |
|---|---|---|---|
demo |
cache/output paths, --viewer, storage floor, --dry-run, --resume, --json, exclusive dry-run plan --output |
None | None |
start |
sensor selection, calibration, output, --yes, --dry-run, --editable, --viewer, storage and verification |
None | None |
setup |
profile, output, calibration and frame options, --json |
None | None |
doctor |
--json |
None | None |
run |
--profile, --output-dir, --min-free-space-gib, --dry-run, --resume, --guided, --yes, --verification |
None | Viewer compatibility options and --no-verify-map |
inspect |
--bag, --symptom, --json, --write |
None | None |
view |
--viewer |
--autoware-core-dir, --work-dir, --runtime-dir, --rebuild, --auto-exit-secs |
None |
sessions |
--status, --limit, --viewer, --json |
None | None |
compare |
--output, --viewer, --json |
None | None |
report |
--json |
None | None |
support |
--output, --json, --first-map |
None | None |
edit |
--plan, --output-dir, --dry-run, --json |
--backend-input, --params, --setup |
None |
merge |
output, alignment, acceptance, transform, dry-run, and JSON options | None | None |
Interactive start calibration review is one fail-closed prompt: it shows the
profile extrinsics once, then asks whether to continue without presenting a
second --yes command. Non-interactive start, setup, and dry-run review keep
printing the exact reviewed rerun command for automation and copy-paste use.
After confirmation, live start skips the repeated setup card and proceeds
directly to map start and durable progress. Setup-only and dry-run output retain
the selected inputs, calibration, and map command because no execution progress
follows them.
For demo, cache presence is not proof of integrity. Dry-run reports
prepared_unverified or archive_unverified; live execution alone promotes
the fixed data after registered archive and extracted-file SHA-256 checks.
--resume is narrower than run --resume: the demo wrapper exposes it only
for terminal post-processing stages and keeps mapping-active state fail-closed.
-h/--help and --help-all are stable for every command. Top-level
--version is also stable. No-argument behavior is mode-sensitive by contract:
TTY input and output select the bounded home, while captured or redirected
execution returns usage exit 2 without reading stdin.
Normal help is the operator view; it contains stable options needed for routine use. Full help is the compatibility view:
lidarslam-map run --help
lidarslam-map run --help-all
--help-all adds advanced runtime controls and deprecated aliases. Hiding a
deprecated option from normal help does not remove it: the parser, completion,
machine-readable inventory and migration documentation retain it throughout
its compatibility window.
The positional names describe directories deliberately:
rosbag2_diris the directory containingmetadata.yaml, never an individual.db3or.mcapstorage file;output_diris a map-run directory or its terminal bundle.
Option tiers
The map-producing run options are ordered by operator intent:
- Core: choose a profile and output directory.
- Lifecycle: plan, reserve storage, or resume post-processing.
- Guided onboarding: show the preflight decision and ask before a long human-operated run.
- Deprecated compatibility: forward old viewer requests to
view. - Verification: retain the required default or explicitly select the
diagnostic-only
offmode.
Viewer construction is not map construction. It is owned by the dedicated
view command, so a viewer failure does not make a completed map look like a
mapping failure. Existing run --viewer ... invocations route through the new
command and remain warning-emitting compatibility aliases during the
published deprecation window. They appear in run --help-all, not the normal
operator help.
The normal view --help contains viewer selection. Viewer build and runtime
controls remain stable but advanced, and are listed by view --help-all.
--verification required is the default. --verification off is a diagnostic
escape hatch, not a normal performance option, and emits a visible warning.
The old --no-verify-map name remains a warning-emitting compatibility alias
during the deprecation window. An unverified run is never described as a
verified success.
start adds only orchestration: it invokes the established sensor setup, map
runner, required verifier, and viewer contracts. Its default browser and
timestamped session directory are beginner defaults; the underlying algorithms
and profile values are unchanged. Calibration is shown before a positive
interactive confirmation, or accepted explicitly with --yes.
An incompatible own-bag input returns exit 2 and the versioned
sensor-setup-rejection-v1 contract. It writes no output, keeps reason and
finding codes stable for automation, and includes human messages plus exact
next actions. A forced incompatible profile uses profile-incompatible; no
safe maintained path uses no-maintained-profile.
After delegation begins, start owns a distinct map-session-recovery-v1
handoff for non-zero map results. This additive artifact preserves diagnosis-v1
and run-manifest-v2 compatibility while giving people and automation stable
runtime/map-quality codes, evidence paths, and exact resume or fresh-output
retry commands. It is written beside the unchanged sensor setup manifest and
does not change or overwrite retained map evidence. Viewer-only failures remain
separate because the map workflow has already completed.
The default terminal projection is deliberately smaller than that artifact: it
shows the first reason, remaining stable codes, one exact Next:, and one
retained Details: path. Per-finding actions, retry and inspect alternatives,
and all evidence paths remain in the JSON and derived session page instead of
competing in the first repair step.
A live start also catches one operator Ctrl-C at the stable CLI boundary. The
dispatcher waits for the start helper instead of abandoning it, and the
helper signals the delegated runner's complete isolated process group. It waits
up to 20 seconds for bounded cleanup and terminal evidence, requests termination
for at most 10 more seconds when needed, then force-reaps the group if it still
has not stopped. The resulting non-zero runner state flows through the unchanged
one-action recovery contract instead of escaping as a Python traceback;
verified success is never synthesized. An expected SIGINT or SIGTERM is not
relabeled as an offline-completion timeout and does not dump the recent launch
log; genuine startup and completion timeouts keep their diagnostics.
Every delegated start also owns an additive map-session-index-v1 contract:
session.json and its derived session.html represent running, verified,
unverified, or action_required through one stable location. Running progress
mirrors atomic run-manifest-v2 stages and adds no estimated-time guarantee.
An unchanged live stage emits at most one terminal heartbeat every 30 seconds
with monotonic elapsed time. The heartbeat performs no session artifact write
and claims neither a percentage, ETA, nor delegated forward progress.
This does not change the view command's verified-map input contract or add a
beginner command. The page is self-contained, escapes operator-controlled text,
and has no network dependencies. Progress generation, browser generation, or
opening is best-effort; run-manifest-v2, validation evidence,
map_session_recovery.json when present, and the delegated map exit code remain
authoritative.
After a successful terminal start, the command prints one bounded VERIFIED or
UNVERIFIED card projected from that index: map output, verification status,
viewer, session index/page, run manifest, first-map receipt, and one exact
Next: command. A verified session adds the read-only Report: preparation
handoff. Viewer
failure makes the single Next: action the view retry and adds a separate
warning. With --viewer none, Next: is the copy-ready command for reopening
the map; an unverified or action-required session also prints its retained
one-line summary. No browser is required.
The additive demo command is a product orchestrator over the existing fixed
public-data script, not another SLAM route. Its read-only JSON exists only with
--dry-run and follows first-map-demo-plan-v1. It refuses unsafe path/output
states and low initial storage before delegation. Each volume exposes exact
additional_bytes_required; a low-storage finding preserves the complete
shell-quoted retry command. An existing map is reusable
only when its first-map receipt is schema-valid and exactly reproducible from
current retained evidence. Viewer failure cannot replace verified success.
The additive quality object does not alter first-map receipt semantics. It
groups the seven required receipt checks into four display cards and preserves
their source IDs. Numeric scoring is intentionally absent. Verification-off
maps to not_verified; missing or semantically invalid evidence maps to
unavailable, so an older or damaged output cannot silently gain PASS status.
The additive sessions command projects existing map-session-index-v1
artifacts into a map-session-catalog-v1 response and local sessions.html.
It does not mutate session or map evidence. Discovery is bounded to direct,
non-symlink child bundles and 2 MiB schema-valid session indexes; result count
is capped at 200. --json is read-only. Browser rendering escapes every
operator-controlled field and links only regular non-symlink session pages.
Invalid candidates contribute only to skipped_invalid.
The additive compare command projects two session indexes into the fixed
map-session-comparison-v1 contract. It treats stale or identity-mismatched
setup evidence as unavailable, compares recorded artifact names without
promoting current-file presence to proof, and emits no numeric score or winner.
Its --json path is read-only. HTML output is self-contained and refuses to
replace symlinks or files not generated by the comparison command.
The additive support command projects one schema-valid session into the
fixed support-bundle-v1 contract. Valid setup evidence is identity-bound;
missing, stale, malformed or symlinked evidence remains unavailable. The
three-member ZIP excludes maps, bags, raw logs, parameter contents, local paths
and command credentials, and is marked for human review. --json is read-only;
ZIP creation is atomic, refuses replacement, and performs no remote mutation.
The additive report command does not create that ZIP. It is a
read-only handoff for a verified session, or a fixed Docker/source demo
output without session.json, whose PASS receipt remains exactly bound to the
retained manifest, diagnosis, and verification log. It prints a
copy-ready result, exact source commit or product-version fallback,
verification summary, the local privacy-bounded JSON receipt path, the
canonical issue form, and the four fields that still need the operator's own
input. An immutable image user is told to replace the suggested release value
with the digest they actually ran. The command never uploads, opens a browser,
or contacts GitHub. The older support <session_bundle> --first-map spelling
remains compatible and resolves to the same implementation and schema.
Missing, stale, malformed, non-PASS, or symlinked evidence fails closed.
run --guided remains a compatibility interaction layer: it repeats the existing
preflight, makes the selected profile, topics, checks, and output location
visible, and asks for confirmation before delegating to the same map runner.
run --guided --yes is the explicit non-terminal form. Both flags leave the
profile defaults and map algorithm unchanged.
Naming rules for new options
- Use lowercase kebab case.
- End directory paths with
-dir. - Include units in numeric names, such as
-secsor-gib. - Render option values consistently as
<id>,<dir>,<file>,<seconds>, or an explicit finite choice set. - Prefer positive behavior and safe defaults. Negative flags are reserved for explicit break-glass behavior.
- Reject zero, negative, non-finite, and malformed numeric values during argument parsing when the contract requires a positive value.
- Reject invalid combinations with exit code
2; do not silently ignore an option. - Add automation output only through a versioned JSON contract.
- A beginner-facing orchestration command must measurably reduce submitted commands and delegate every technical lifecycle to its existing owner.
Every public addition must update contracts/cli-v1.json, command help,
documentation, and tests in the same change. CI compares the manifest with
the exact command and option sets in shell completion, the flags and metavars
rendered by each command, and every finite completion choice. An undocumented
option, extra stale completion, changed value shape, or missing choice fails
the contract test.
Maintained workflow profile IDs and descriptions have one installed registry,
product_profiles.py. Doctor help, runner choices and help, the CLI contract,
completion, and release bundles are tested against that registry so a profile
cannot be added to only one command surface.
Migration sequence
lidarslam-map view <output_dir>owns optional viewer startup.run --viewer ...routes throughviewand emits a deprecation warning while preserving its previous combined-command exit behavior.--verification {required,off}makes the safety mode explicit;--no-verify-mapremains its warning-emitting compatibility alias.--helppresents routine stable options;--help-allpreserves full discoverability of advanced and deprecated options.- Freeze both help levels, exit codes, JSON schemas, and shell completion in the Humble and Jazzy installed-CLI checks.
No deprecated or provisional option is removed merely because a replacement exists. Removal follows the compatibility window above.