OSIRIS JSON Toolbox CLI - Command Orchestration and CI/CD Behavior
| Field | Value |
|---|---|
| Authors | Tia Zanella skhell |
| Revision | 1.0.0-DRAFT |
| Creation date | 14 February 2026 |
| Last revision date | 19 February 2026 |
| Status | Draft |
| Document ID | OSIRIS-ADG-TLB-CLI-1.0 |
| Document URI | OSIRIS-ADG-TLB-CLI-1.0 |
| Document Name | OSIRIS JSON Toolbox CLI - Command Orchestration and CI/CD Behavior |
| Specification ID | OSIRIS-1.0 |
| Specification URI | OSIRIS-1.0 |
| Schema URI | OSIRIS-1.0 |
| License | CC BY 4.0 |
| Repository | github.com/osirisjson/osiris-toolbox |
Table of Content
1 CLI design principles
@osirisjson/cli is the primary CI-friendly and developer-friendly interface to the OSIRIS validation engine. It reads OSIRIS documents from disk or stdin, delegates validation to @osirisjson/core and presents results in both human and machine-readable formats. The CLI MUST NOT re-implement validation logic; it is strictly an orchestration and presentation layer.
[!NOTE] Back-reference: The CLI’s role and boundaries are defined in OSIRIS-ADG-1.0 section 2.2.3. Validation engine internals (pipeline stages, diagnostics model, schema loading) are defined in OSIRIS-ADG-TLB-CORE-1.0. The diagnostic code registry and severity model are defined in OSIRIS-ADG-VL-1.0.
1.1 Unix philosophy and composition
The CLI follows Unix conventions so it composes naturally with existing shell workflows and CI systems.
Separation of streams:
stdoutcarries command results (validation diagnostics and result envelopes). This is the only stream that downstream tools (pipes, redirects,jq) SHOULD consume.stderrcarries operational messages only: usage errors, unreadable files, invalid JSON parse errors, and optional progress indicators.stderrMUST NOT contain validation diagnostics, and MUST NOT contain messages that change or explain validation outcomes (e.g. schema fallback decisions).
Quiet JSON mode:
When --format json is active, the CLI SHOULD keep stderr empty unless an OPERATIONAL_ERROR occurs. Progress indicators or summaries MAY be enabled only behind an explicit verbosity flag (e.g. --verbose), and MUST remain strictly optional.
Stdin support:
The CLI MUST accept documents from stdin when no file arguments are provided or when - is passed explicitly, enabling pipeline composition (e.g. cat osiris-document-example.json | npx @osirisjson/cli validate -). When reading from stdin, the CLI SHOULD buffer the full input before validation to provide accurate source-text ranges.
Single responsibility:
Each CLI command does one thing. The validate command validates; it does not transform, merge or generate documents. Future commands (e.g. format, info) SHOULD follow the same pattern: one verb, one job, composable via pipes.
1.2 Deterministic behavior
CI pipelines depend on predictable output. The CLI MUST produce identical results for identical inputs regardless of environment, locale or terminal capabilities.
Invariants:
- Same document + same flags + same
@osirisjson/coreversion = same exit code and same diagnostics (ordering, content, count). - No network calls during validation. Schema resolution is offline-first (see section 2.3).
- Color and formatting are presentation concerns that MUST NOT affect the content of
stdoutwhen--format jsonis active. - Timestamps or wall-clock values MUST NOT appear in validation output. Diagnostics reference document content, not execution time.
Environment isolation: The CLI MUST NOT read implicit configuration from home directories, environment variables or global config files unless explicitly documented. All behavior-affecting options are passed via flags. This prevents “works on my machine” drift between local and CI environments.
2 Command orchestration
This chapter defines how the CLI invokes the validation engine and maps results to exit codes.
2.1 Validation pipeline invocation
The validate command is the CLI’s primary entry point. It reads one or more OSIRIS documents, invokes @osirisjson/core and emits results.
Invocation patterns:
# Single file
npx @osirisjson/cli validate osiris-document-example.json
# Multiple files
npx @osirisjson/cli validate osiris-document-example-01.json osiris-document-example-02.json
# Directory (validates all .json files, non-recursive by default)
npx @osirisjson/cli validate ./exports/
# Stdin
cat osiris-document-example.json | npx @osirisjson/cli validate -
# CI with machine output and strict profile
npx @osirisjson/cli validate --profile strict --format json ./exports/
Profile selection:
The CLI passes the --profile flag value directly to @osirisjson/core. The CLI MUST NOT interpret profile semantics; it is a pass-through.
| Flag | Engine profile | Behavior |
|---|---|---|
--profile basic | basic | Stage 1 only (structural schema validation) |
--profile default (or omitted) | default | Stage 1 + Stage 2 (structural + semantic) |
--profile strict | strict | Stage 1 + Stage 2 + Stage 3 (all levels including domain best practices) |
Multi-file behavior:
When validating multiple files, the CLI SHOULD validate each file independently and SHOULD continue processing remaining inputs even if one input encounters an OPERATIONAL_ERROR. Each input produces its own result envelope (and its own Diagnostic[] when validation executes).
The CLI MAY validate files concurrently using worker threads but MUST present results grouped by file in a deterministic order (lexicographic by normalized file path).
2.2 Exit code strategy
Exit codes are the CLI’s primary contract with CI systems. They MUST be stable within a toolbox MAJOR version.
| Exit code | Name | Meaning |
|---|---|---|
0 | SUCCESS | All inputs were processed; no diagnostics with severity: "error" were emitted. Warnings and info diagnostics may be present. |
1 | VALIDATION_ERROR | One or more inputs produced at least one diagnostic with severity: "error". The CLI executed the validation pipeline for those inputs. This includes compatibility errors (e.g. unsupported document/schema MAJOR) when they can be expressed as diagnostics. |
2 | OPERATIONAL_ERROR | The CLI could not process one or more inputs due to pre-validation failures: file not found, unreadable input, invalid JSON parse, invalid flags, I/O errors, or other failures that prevent validation from executing. |
Design rationale:
- Exit
0vs1is the CI gate: pipelines fail on1, pass on0. Warnings alone MUST NOT cause exit1. - Exit
2distinguishes “the tool could not run” from “the document failed validation”.
Multi-file exit code resolution: When validating multiple inputs, the CLI exits with the highest exit code encountered across all inputs:
- If any input results in exit
2, the overall exit is2. - Else if any input results in exit
1, the overall exit is1. - Else the overall exit is
0.
2.3 Schema resolution precedence
The CLI resolves the JSON Schema used for Stage 1 validation following a strict precedence order. This is the CLI-layer resolution that feeds into @osirisjson/core’s schema loading (defined in OSIRIS-ADG-TLB-CORE-1.0 section 1.1).
Resolution order (highest to lowest precedence):
-
CLI flag (
--schema <path>): An explicit local path to a schema file. When provided, this overrides all other sources. The CLI loads the file and passes it to the engine. This is intended for development, testing against draft schemas or enterprise environments with mirrored schemas. -
Document
$schemafield: If no CLI flag is provided, the CLI inspects the document’s$schemafield. The$schemaURL is used as a version hint (e.g. extractingv1.0fromhttps://osirisjson.org/schema/v1.0/osiris.schema.json) to select the appropriate bundled schema. The CLI MUST NOT fetch the URL from the network; it resolves locally using bundled or cached schemas. -
Bundled local default: If neither a CLI flag nor a
$schemafield is present, the CLI falls back to the highest bundled schema version that matches the document’sversionfield (SemVerMAJOR.MINORrouting as defined in OSIRIS-ADG-TLB-CORE-1.0 section 1.1.1).
Offline-first guarantee:
The CLI MUST function fully offline using bundled schemas. No network call is made during validation. A separate osiris schema update command (or equivalent) MAY be provided to refresh a local cache, but this is never invoked implicitly.
flowchart TD
START["Resolve schema"] --> FLAG{"--schema flag?"}
FLAG -- "yes" --> LOAD_FLAG["Load schema
from flag path"]
FLAG -- "no" --> DOLLAR{"$schema field
in document?"}
DOLLAR -- "yes" --> EXTRACT["Extract version hint
from $schema URL"]
DOLLAR -- "no" --> VERSION["Read document
version field"]
EXTRACT --> BUNDLED["Match bundled schema
by MAJOR.MINOR"]
VERSION --> BUNDLED
LOAD_FLAG --> ENGINE["Pass to
@osirisjson/core"]
BUNDLED --> ENGINE
3 Output strategy
The CLI supports two output modes, selected via the --format flag. The default is text (human-readable); json produces machine-readable output for CI pipelines, scripts and downstream tooling.
3.1 Human-readable output
Human-readable output (--format text, the default) is designed for terminal use during local development.
Diagnostic rendering: Each diagnostic is rendered as a single block with file path, location, severity, code and message. When source-text ranges are available, the CLI SHOULD display a code snippet with the relevant line highlighted.
osiris-document-example.json:14:5 error V-REF-002
Connection target "aws::nonexistent" not found in topology.resources
13 | "source": "aws::i-abc123",
14 | "target": "aws::nonexistent",
15 | "type": "network"
osiris-document-example.json:28:3 warning V-DOM-001
Resource missing provider.native_id (recommended for provider correlation)
Color and formatting:
- Colors SHOULD be enabled when
stdoutis a TTY and disabled otherwise (e.g. when piped). The--colorflag (always|never|auto) overrides auto-detection. - Severity indicators use color:
errorin red,warningin yellow,infoin blue/cyan. - Colors are a presentation-only concern and MUST NOT affect the textual content of diagnostics.
Summary line:
After all diagnostics, the CLI SHOULD print a human summary to stderr only when --format text is active:
2 errors, 1 warning in osiris-document-example.json
osiris-document-example.json: OSIRIS validation failed
3.2 Machine-readable output
Machine-readable output (--format json) produces structured JSON for CI parsing, dashboards and scripting. This format is the CLI’s stable contract for programmatic consumers.
Path normalization:
- The
filefield MUST be stable and deterministic. - When the input is
stdin,fileMUST be"-". - For file and directory inputs,
fileSHOULD be emitted as a normalized path using/as separator (even on Windows). Implementations SHOULD NOT canonicalize paths to absolute form by default.
Range indexing:
- In JSON output,
range.start.line,range.start.character,range.end.line,range.end.characterMUST be 0-based (LSP-style). - In human text output, line/column rendering SHOULD be 1-based for readability.
Result envelope: Each processed input produces one JSON object with the following high-level fields:
status:"success" | "validation_error" | "operational_error"valid: boolean (meaningful only whenstatusis"success"or"validation_error")diagnostics: present only when validation executed (may be empty)operationalError: present only whenstatusis"operational_error"
Single-input output (JSON object):
When validating a single input, the CLI emits a single JSON object to stdout:
{
"file": "osiris-document-example.json",
"status": "validation_error",
"valid": false,
"profile": "default",
"counts": { "error": 2, "warning": 1, "info": 0 },
"diagnostics": [
{
"code": "V-REF-002",
"severity": "error",
"message": "Connection target \"aws::nonexistent\" not found in topology.resources",
"path": "/topology/connections/0/target",
"range": {
"start": { "line": 13, "character": 4 },
"end": { "line": 13, "character": 36 }
}
}
]
}
Operational errors in JSON mode:
If the CLI cannot process an input (e.g. unreadable file, invalid JSON), it MUST still emit one JSON object for that input with status: "operational_error", and include operationalError. In this case, diagnostics MUST be omitted (or empty) because validation did not execute.
{
"file": "exports/broken.json",
"status": "operational_error",
"valid": false,
"profile": "default",
"counts": { "error": 0, "warning": 0, "info": 0 },
"operationalError": {
"kind": "invalid_json",
"message": "Unexpected token } at line 42"
}
}
Multi-file output (NDJSON):
When validating multiple inputs, the CLI emits one JSON object per line (Newline-Delimited JSON) to stdout. Each line follows the same envelope schema as the single-input object above. NDJSON enables streaming processing, jq per-line filtering and straightforward CI log parsing without buffering the entire result set.
npx @osirisjson/cli validate --format json ./exports/ | jq 'select(.status != "success")'
Output shape stability:
The JSON output shape (field names, types and nesting) is a stable contract within a toolbox MAJOR version. New optional fields MAY be added in MINOR releases. Existing fields MUST NOT be removed or change meaning without a MAJOR bump. Consumers HOULD ignore unknown fields for forward compatibility.
Diagnostic serialization:
Diagnostics in JSON output MUST serialize the same fields as the Diagnostic interface defined in OSIRIS-ADG-TLB-CORE-1.0 section 2.1.1. Optional fields (range, related, fix) are omitted when absent rather than emitted as null.