Status: draft
Scope: the v0 CLI for the gm tool. Three commands (validate,
compile, import-owl) plus global conventions for output, errors, and
exit codes. Out-of-scope items enumerated in §8.
- Minimal surface. Three commands cover both user workflows end to end. Nothing else ships in v0.
- Composable. Output is just text, stdout is where results go, exit
codes are honest.
gm compile … | bq queryworks; CI parses errors with--json. - Predictable. Same inputs → same output. Validation is strict and runs implicitly before compilation.
Two starting conditions cover the common cases.
| Step | Action | Command |
|---|---|---|
| 1 | Get an ontology: hand-author finance.ontology.yaml, or import from OWL |
gm import-owl fibo.ttl --include-namespace <…> -o finance.ontology.yaml |
| 2 | Resolve FILL_IN placeholders if any |
— (text editor) |
| 3 | Check the ontology is valid | gm validate finance.ontology.yaml |
| 4 | Design and create warehouse tables | — (external) |
| 5 | Author finance-bq-prod.binding.yaml |
— (text editor) |
| 6 | Check the binding | gm validate finance-bq-prod.binding.yaml |
| 7 | Compile to DDL | gm compile finance-bq-prod.binding.yaml |
| 8 | Apply DDL | — (external) |
| Step | Action | Command |
|---|---|---|
| 1 | Inspect existing table schemas | — (external) |
| 2 | Author finance.ontology.yaml to describe the tables |
— (text editor) |
| 3 | Check the ontology is valid | gm validate finance.ontology.yaml |
| 4 | Author finance-bq-prod.binding.yaml |
— (text editor) |
| 5 | Check the binding | gm validate finance-bq-prod.binding.yaml |
| 6 | Compile to DDL | gm compile finance-bq-prod.binding.yaml |
| 7 | Apply DDL (property graph only; tables already exist) | — (external) |
Installed binary gm. Subcommand style is flat verb-noun hyphenated
(gm import-owl, not gm import owl).
- stdout — the primary result: DDL text (
gm compile), imported YAML (gm import-owlwithout-o), nothing on success (gm validate). - stderr — diagnostics, warnings, human-readable errors.
-o <file>/--out <file>— redirect stdout to a file. Where applicable (gm compile,gm import-owl).
| Code | Meaning |
|---|---|
| 0 | Success. No errors; warnings may have been printed. |
| 1 | Validation or compilation error (user-fixable). |
| 2 | Usage error (bad flag, missing file). |
| 3 | Internal error (unexpected exception). |
Default is human-readable, one line per error in the form:
<file>:<line>:<col>: <rule> — <message>
Example:
finance.ontology.yaml:47:5: ontology-r11 — Entity "Account" has no primary key
--json emits a JSON array of structured error objects with fields
file, line, col, rule, severity (error | warning),
message. Warnings do not affect the exit code.
- Suggested suffixes.
*.ontology.yaml,*.binding.yaml. The loader detects file kind by the top-level key (ontology:orbinding:), so any extension is accepted. - OWL source. File extension selects the parser:
.ttl(Turtle),.owl/.rdf(RDF/XML).
Check that a single YAML file conforms to its spec and cross-references resolve.
gm validate <file>
- Loader detects ontology vs binding from the top-level key.
- Ontology → checked against
ontology.md§10. - Binding → checked against
binding.md§9. The CLI locates the companion ontology (named byontology:in the binding, looked up as<name>.ontology.yamlin the same directory) for cross-validation. If the companion is not found, validation fails with exit 2 (cli-missing-ontology). Use--ontology PATHto point at a specific ontology file and skip auto-discovery.
| Flag | Purpose |
|---|---|
--json |
Structured error output (see §3). |
--ontology <path> |
For binding files: path to the companion ontology. Overrides auto-discovery of <name>.ontology.yaml next to the binding. |
On success, nothing is written to stdout.
Emit DDL from a binding. The companion ontology is located by the same
rule as gm validate (§4).
gm compile <binding> [--ontology <path>] [-o <out>]
- Input must be a binding YAML file. Passing an ontology file (or any
other non-binding YAML) exits 2 with
cli-wrong-kind. - Runs validation implicitly on both files before emission. Any error fails the compile; no partial DDL is emitted.
- Writes DDL to stdout unless
-ois given.
| Flag | Purpose |
|---|---|
-o <file>, --output <file> |
Write DDL to file instead of stdout. |
--ontology <path> |
Path to the companion ontology. Overrides auto-discovery (same as gm validate). |
--json |
Structured errors for the implicit validation step. |
--emit-concept-index |
Append CREATE OR REPLACE TABLE SQL for the concept index + __meta sibling. Requires --concept-index-table. See concept-index.md. |
--concept-index-table <project.dataset.table> |
Fully-qualified destination for the concept index. Required when --emit-concept-index is set; no silent global default. The __meta sibling is suffixed automatically. |
--compiler-version <str> |
Override the version string flowed into compile_fingerprint. Defaults to the installed package version. Only honored with --emit-concept-index. |
On any validation or compilation error, no DDL is emitted — even partially.
When --emit-concept-index is set, the output combines the property-graph
DDL with two CREATE OR REPLACE TABLE statements emitted by the
sibling compile_concept_index emitter (the main concept index and its
__meta provenance table). The combined output is still a single text
stream; pipe it into bq query or write it to a file with -o. Without
the flag, output is byte-identical to plain gm compile.
The required --concept-index-table value must be a fully-qualified
project.dataset.table triple. Each segment must match
^[A-Za-z0-9_-]+$; backticks are added by the emitter (do not
pre-quote). See concept-index.md for the full
schema, provenance contract, and SQL patterns.
Example:
gm compile finance-bq-prod.binding.yaml \
--emit-concept-index \
--concept-index-table my-proj.my_ds.ontology_concept_index \
-o graph_ddl.sqlWhen writing to a file, the conventional name is graph_ddl.sql.
This contrasts with table_ddl.sql, the output of gm scaffold, so a
directory containing both artifacts is self-describing. The convention
is advisory — -o accepts any path.
Read OWL sources and emit a *.ontology.yaml (see owl-import.md).
gm import-owl <source>... --include-namespace <iri>... [-o <out>]
[--format ttl|rdfxml] [--language <tag>] [--json]
- One or more OWL source files (Turtle, RDF/XML).
- At least one
--include-namespacerequired; multiple allowed. - Recognizes both OWL and SKOS constructs; SKOS concepts become
abstract entities, SKOS graph predicates become abstract
relationships, and SKOS literals become annotations. See
owl-import.md§19 for the full mapping. - Output uses
FILL_INfor ambiguities and annotations for dropped OWL features (seeowl-import.md§11, §13).FILL_INcausesgm validateto fail until resolved.
| Flag | Purpose |
|---|---|
--include-namespace <iri> |
Required, repeatable. |
-o <file>, --out <file> |
Write YAML to file instead of stdout. |
--format ttl|rdfxml |
Override parser selection from file extension. |
--language <tag> |
BCP-47 language tag for label selection (default en). Other-language labels become language-suffixed annotations. |
--json |
Structured drop-and-placeholder summary. |
Drop summary is printed to stderr regardless of --json. It includes
SKOS counts (concepts imported as abstract, relationships imported as
abstract, annotations preserved, labels discarded by language
selection, external match targets, generic literal annotations) and a
hint when every imported entity is abstract.
- Warnings as errors. A
--strictflag that turns warnings into exit-1 errors is common in similar tools. Defer until CI users ask. - Log verbosity. No
--verbose/-vin v0. Validation and compile output are already structured enough; add only if debugging demands it. - Config file. A
gm.tomlor similar for per-project defaults (namespace filters, target dataset) would simplify repeated invocations. Defer until a concrete need surfaces.
gm init— scaffold a minimal project. Users can copy fromdocs/distillation/examples/once that exists.gm inspect-schema— reverse-engineer a skeleton ontology from an existing warehouse dataset. Useful for Workflow B but a significant amount of backend-specific code.gm deploy— apply DDL to a live backend. Explicitly off-limits percompilation.md§1.gm diff— compare two compilations. Text diff of DDL output covers the need.- Shell completion — post-v0.
- Installation and packaging — separate concern (PyPI, homebrew, etc.).