Command line
The Rules block ships four top-level kis commands: rules runs a rule set over JSON files, ocr
runs a rule set over paired page facts and bounding boxes, bbox inspects a bounding-box document
without running any rules, and hocr2bbox converts hOCR into the .bbox files the other three
consume.
| Command | What it does | Runs rules |
|---|---|---|
kis rules | Globs *.json in a directory, one rule execution per file | yes |
kis ocr page | One execution per <prefix>.json + <prefix>.bbox pair | yes |
kis ocr doc | All pairs merged into one document, one execution total | yes |
kis bbox tables | Detect and print every table | no |
kis bbox table | Print the one table nearest an anchor | no |
kis bbox phrase | Find a phrase, with page, coordinates and context | no |
kis bbox snippet | Extract text between two phrases | no |
kis bbox snippets | Extract several named snippets in one pass | no |
kis hocr2bbox | Convert hOCR to .bbox JSON | no |
The document surface is not CLI-only. rules.svc reaches the same capabilities — the document
model, OCR ingestion, field, form and checkbox extraction, tables and repeaters, matching and
confidence, and the document bindings a rule calls. What differs is where the input comes from:
these commands read .json and .bbox files from disk, while the service takes the same document
input on its execute-rule request. The kis bbox subcommands are local inspection tools — they
print what they found and run no rules. See
Running the service.
Installing the commands
Section titled “Installing the commands”All four commands are proxy stubs on the kis binary. Each one forwards its arguments verbatim to a
separately installed rules plugin executable, which is where the actual implementation lives. kis
looks for that executable in this order and takes the first executable match:
- The directory containing the running
kisbinary. ~/.kisai/bin/.- Every entry of
$KIS_PLUGIN_PATH. - Every entry of
$PATH.
kis also passes the program name you typed to the plugin, so kis rules --help prints
Usage: kis rules [flags].
Global flags
Section titled “Global flags”Because the proxy commands disable flag parsing, flags for kis itself must come before the
command name. Anything after it is forwarded to the plugin untouched.
kis --quiet rules -r rules/ -i pages/| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--quiet | -q | bool | false | Suppress non-error output |
--tenant | string | "" | Tenant override | |
--log-level | -l | string | error | trace, debug, info, warn, error |
--log-to | string | stderr | stderr, stdout, or a file path | |
--log-format | string | text | text or json | |
--env-file | string | "" | Env YAML file to use instead of ~/.kisai/env.yaml |
The plugin itself understands -l/--log-level and --env-file anywhere after the command name, so
kis rules -l debug ... works. The other four are interpreted only in the leading position.
Environment variables on this path: KIS_PLUGIN_PATH (extra plugin search directories), KIS_ENV
(selects the active env.yaml block), KIS_ENV_FILE (overrides the global env file), and
KIS_DEBUG, KIS_QUIET, KIS_TENANT, KIS_LOGLEVEL, KIS_LOGTO, KIS_LOGFORMAT, which seed the
context handed to the plugin.
Flag defaults from env.yaml
Section titled “Flag defaults from env.yaml”Before a command runs, any flag you did not type on the command line is filled from env.yaml. Keys
are the flag’s long name verbatim — lowercase, no prefix, no command nesting.
# ./env.yaml, or ~/.kisai/env.yamldefault: workers: 4 pattern: "page*.json" log-level: infoTwo files feed flag defaults, lowest precedence first: the global file ($KIS_ENV_FILE or
~/.kisai/env.yaml), then ./env.yaml. Within each file only the block named by $KIS_ENV is read,
falling back to default. Resolution is: explicit flag > env.yaml > compiled-in default. The
ambient OS environment never feeds flag values. env-file cannot be set this way — it selects the
file being loaded.
kis rules
Section titled “kis rules”kis rules -r <rulefile|ruledir> [flags]Runs one rule execution per file matched by <--input>/<--pattern>. All input selection is through
-i and -p; positional arguments are accepted by the parser and then ignored without a warning, so
kis rules -r r.grl page1.json runs over ./*.json, not over page1.json. Each input file’s
top-level JSON keys become the fact names rules read.
| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--rules | -r | string slice | — (required) | Rule file or directory of rules |
--input | -i | string | . | Directory of JSON files to process |
--pattern | -p | string | *.json | Basename glob, joined to -i, non-recursive |
--output | -o | string | "" | Output directory; only honoured with --update |
--key | -k | string | "" | Nest the result under this key instead of merging at the root |
--update | bool | false | Write results instead of only printing them | |
--facts | -f | string slice | nil | Extra fact file, key=path or bare path |
--vars | -v | string slice | nil | key=value facts, injected as strings |
--bbox | -b | string slice | nil | Bounding-box file to inject, [key=]path |
--with-bbox | bool | false | Also load <input>.bbox beside each <input>.json | |
--with-bbox-name | string | bbox | Document name for the --with-bbox sidecar | |
--recursive | -R | bool | false | Recurse when discovering rule files |
--workers | -w | int | 1 | Parallel executions, clamped to [1, files matched] |
--history | bool | false | Print the history of value changes | |
--audit | bool | false | Print the audit log | |
--history-audit | string | "" | Directory for the -hist-audit.json sidecars | |
--ruleset | string | rules | Accepted and ignored — see below | |
--debug | bool | false | Print load and worker progress plus each file’s output |
--rules, --facts, --vars and --bbox are repeatable and also split on commas, so
-r a.grl,b.grl is two values and a path containing a comma breaks.
Output modes
Section titled “Output modes”kis rules -r rules/ -i pages/Result for /work/pages/page1.json:{ "document_type": "BANK_STATEMENT", "confidence": 0.95}Processed 1/1 file(s) successfullyAdd --update to write. With no -o, or an -o equal to -i, the results are merged into each
source file. With a different -o, only the rule results are written to the mirrored path and the
source is left alone.
kis rules -r rules/ -i pages/ --updatekis rules -r rules/ -i pages/ -o results/ -k rules_result --updateAn execution that produced an empty result map writes nothing at all, even with --update, and
prints nothing beyond the Processed N/M line.
Injecting facts, variables and documents
Section titled “Injecting facts, variables and documents”kis rules -r rules/ -i pages/ -f ref=lookup.json -v env=prod -b mydoc=pages/page1.bbox-f key=path nests the file’s contents under key; a bare -f path merges the file’s top-level
keys into the fact root. -v values are always strings — -v threshold=10 gives a rule the string
"10", never the number. Variables overlay facts loaded from -f.
For a sidecar per input file, use --with-bbox, and name it to match what your rules call:
kis rules -r classify.grl -i pages/ --with-bbox --with-bbox-name pagekis ocr page
Section titled “kis ocr page”kis ocr page -r <rulefile|ruledir> [prefix|file|dir]...Resolves inputs to prefixes and runs the rule set once per prefix. Both <prefix>.json (facts) and
<prefix>.bbox (bounding boxes) must exist.
A positional argument may be a bare prefix name (resolved against -i), a .json or .bbox path
(the extension is stripped), or a directory (globbed with -p). With no positional arguments the
-i directory itself is globbed. Duplicates are removed.
kis ocr page -r rules.grl page1kis ocr page -r rules/ page1 page2 page3kis ocr page -r rules/ pages/*.jsonkis ocr page -r rules/ pages/kis ocr page -r rules/ -i pages/ -p "page*.json"kis ocr page -r rules/ -i pages/ -o results/kis ocr page -r rules/ --update pages/kis ocr page -r rules/ --skip-pattern '*-extract.json' pages/| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--rules | -r | string slice | — (required) | Rule file or directory of rules |
--input | -i | string | . | Base directory for resolving prefixes |
--pattern | -p | string | *.json | Basename glob for directory arguments |
--skip-pattern | string slice | nil | Extra basename globs to exclude | |
--output | -o | string | "" | Output directory, mirroring the input’s relative path |
--update | bool | false | Merge results into the source .json in place | |
--key | -k | string | "" | Nest the result under this key |
--ruleset | string | rules | Name the loaded rule set is compiled under | |
--facts | -f | string slice | nil | Extra fact files, key=path or bare path |
--vars | -v | string slice | nil | key=value facts, injected as strings |
--bbox-name | string | page | Document name the page’s boxes are injected under | |
--schema | string slice | nil | A .schema file to register (repeatable) | |
--schemas | string slice | nil | Directory of *.schema files, non-recursive | |
--recursive-rules | bool | false | Recurse when discovering rule files | |
--workers | -w | int | 1 | Parallel page executions, clamped to [1, prefixes] |
--history | bool | false | Print the history of value changes | |
--audit | bool | false | Print the audit log | |
--history-audit | string | "" | Directory for the -hist-audit.json sidecars | |
--debug | bool | false | Enable debug messages |
*-hist-audit.json is always skipped, without asking, in addition to any --skip-pattern you give.
An invalid --skip-pattern glob fails up front with invalid --skip-pattern "<pat>": <err>.
With neither -o nor --update, results go to stdout:
kis ocr page -r classify.grl -i pages --history --audit page1--- History for /work/pages/page1.json --- 1. [DetectInvoice] doctype = "invoice"
--- Audit for /work/pages/page1.json --- 1. [DetectInvoice] executed 2. [DetectInvoice] matched the phrase 'Invoice Number'
Result for /work/pages/page1.json:{ "doctype": "invoice"}Processed 1/1 prefix(es) successfullyThe executed audit entry is added by the engine for every rule that fires; the second line is the
rule’s own audit.Log call.
Registering schemas
Section titled “Registering schemas”kis ocr page -r rules/ --schema schemas/invoice.schema pages/kis ocr doc -r rules/ --schemas schemas/ pages/The filename minus .schema is the name rules call it by, so invoice.schema registers as
invoice. --schemas is non-recursive. Duplicate names across --schema and --schemas are a hard
error. Neither flag exists on kis rules. See
Schema-driven extraction.
kis ocr doc
Section titled “kis ocr doc”kis ocr doc -r <rulefile|ruledir> [prefix|file|dir]...Resolves the same prefixes as ocr page, then aggregates: every page’s facts are injected as one
array under --facts-key, every page’s boxes merge into one multi-page document under
--bbox-name, and the rule set runs exactly once.
| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--rules | -r | string slice | — (required) | Rule file or directory of rules |
--input | -i | string | . | Base directory for resolving prefixes |
--pattern | -p | string | *.json | Basename glob for directory arguments |
--skip-pattern | string slice | nil | Extra basename globs to exclude | |
--output | -o | string | "" (stdout) | Output file; parent directories are created |
--key | -k | string | "" | Nest the result under this key |
--ruleset | string | rules | Name the loaded rule set is compiled under | |
--facts | -f | string slice | nil | Extra fact files, key=path or bare path |
--facts-key | string | pages | Key holding the per-page facts array | |
--vars | -v | string slice | nil | key=value facts, injected as strings |
--bbox-name | string | doc | Name of the merged multi-page document | |
--schema | string slice | nil | A .schema file to register (repeatable) | |
--schemas | string slice | nil | Directory of *.schema files, non-recursive | |
--recursive-rules | bool | false | Recurse when discovering rule files | |
--history | bool | false | Print the history of value changes | |
--audit | bool | false | Print the audit log | |
--history-audit | string | "" | Directory for the -hist-audit.json sidecar | |
--debug | bool | false | Enable debug messages |
There is no --workers — this is a single execution.
kis ocr doc -r docrule.grl -i pages page1 page2kis ocr doc -r docrule.grl -i pages -o results/document.json page1 page2{ "doctype": "invoice"}Merging renumbers pages: each page’s number, and each word’s page, becomes a sequential index
over the whole merged document. Rules keyed on the original page numbers see the merged numbering.
Which name a rule uses
Section titled “Which name a rule uses”Rules address a loaded bounding-box document by name, and each command injects it under a different default.
| Command | Flag that sets the name | Default name |
|---|---|---|
kis rules -b [key=]file | the key= prefix | bbox |
kis rules --with-bbox | --with-bbox-name | bbox |
kis ocr page | --bbox-name | page |
kis ocr doc | --bbox-name | doc |
The same run over HTTP
Section titled “The same run over HTTP”rules.svc runs a document rule set from the same inputs. Facts sit at the top level of the request
body exactly as they do in an input .json, and documents arrive under the reserved bbox key,
keyed by the name the rules address them by — the HTTP counterpart of -b <key>=<file> and
--bbox-name.
curl -X POST https://rules.example.com/rule -H 'Authorization: Bearer <tenant-jwt>' -H 'X-Customer: acme' -H 'X-Product: erp' -H 'X-Env: prod' -H 'X-Tenant: eu1' -d @request.json{ "name": "rules", "doctype_hint": "invoice", "bbox": { "page": { "pages": [ { "number": 1, "width": 1224, "height": 1584, "words": [] } ] } }}Each document value is the .bbox JSON kis hocr2bbox produces, sent inline instead of read from
disk. The response is the out map — the same object kis rules prints under Result for .... The
name match is as strict as it is on the CLI: bbox.Get("page") needs a bbox entry called page.
kis bbox
Section titled “kis bbox”Read-only analysis of .bbox files. No rules are loaded and nothing is written back to the input.
Every subcommand concatenates its repeatable -i/--input values with its positional file
arguments and treats the result as one input list, so shell globs and -i mix freely. All pages
across all inputs are renumbered sequentially into one merged document before analysis. -i,
--snip and -H are taken literally — they do not split on commas, so repeat the flag instead.
A miss is not an error. No matches found for phrase: "<p>", No snippet found between "<s>" and "<e>", No table found near anchor: <a> and No tables detected. are all printed to the output
stream — so they land in an -o file too — and the command exits 0. Of the checks these commands
run on what they found, only bbox table -H validation failure exits non-zero. An unreadable input
file always exits non-zero.
kis bbox tables
Section titled “kis bbox tables”kis bbox tables [files...]| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--input | -i | string array | nil | Path to a bounding-box file (repeatable) |
--format | -f | string | text | text, json or csv |
--output | -o | string | "" (stdout) | Output file path |
kis bbox tables data/page1.bboxkis bbox tables *.bbox -f csv -o tables.csv=== Table 1 (Page 1) ===Dimensions: 2 rows x 3 columns
Invoice | Number | INV-42Total | | 120.00Cells are padded to the widest value in their column, minimum width 3. When the table has detected
headers the text output adds a Headers: ... line and a dashed separator under the header rows.
-f json emits {"tables":[{index,page,rows,cols,header_rows,headers?,data}]}. -f csv prefixes
each table with a # Table N (Page P) comment line and separates tables with a blank line.
kis bbox table
Section titled “kis bbox table”kis bbox table -a "<anchor>" [files...]| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--anchor | -a | string | — (required) | Anchor text; the nearest table is returned |
--input | -i | string array | nil | Path to a bounding-box file (repeatable) |
--header | -H | string array | nil | An expected column header (repeatable) |
--format | -f | string | text | text, json or csv |
--output | -o | string | "" (stdout) | Output file path |
kis bbox table -a "Price List" -H "Item" -H "Price" -H "Qty" doc.bboxkis bbox table -a "Summary" -f json -o table.json doc.bboxEvery -H value must be present or the command prints
Header validation failed: missing headers: <list> (found: <list>) and exits non-zero. A table with
no detected header row fails the same way, with Header validation failed: table has no headers.
Comparison is case-insensitive and trims whitespace.
The JSON and CSV shapes differ from tables: table -f json emits a bare object with no index
field, and table -f csv emits bare rows with no # Table comment line. A consumer cannot treat the
two interchangeably.
kis bbox phrase
Section titled “kis bbox phrase”kis bbox phrase -p "<phrase>" [files...]| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--phrase | -p | string | — (required) | Phrase to search for; multi-word is supported |
--input | -i | string array | nil | Path to a bounding-box file (repeatable) |
--before | -B | int | 3 | Context lines before each match |
--after | -A | int | 3 | Context lines after each match |
--format | -f | string | text | text or json |
--output | -o | string | "" (stdout) | Output file path |
--case-insensitive | bool | false | Ignore case; matching is case-sensitive by default | |
--fuzzy | bool | false | Enable Levenshtein fuzzy matching | |
--max-dist-word | int | 2 | Max edit distance per word (fuzzy only) | |
--max-dist-total | int | 3 | Max total edit distance for the phrase (fuzzy only) |
kis bbox phrase -p "Invoice Number" data/page1.bboxkis bbox phrase -p "Inviice Numbr" --fuzzy --max-dist-word 2 --max-dist-total 3 doc.bboxFound 1 match(es) for phrase "Invoice Number"
=== Match 1 (Page 1) ===Location: (72.0, 100.0) - (195.0, 112.0)Line: 1
>> Invoice Number INV-42 Total 120.00-f json emits {phrase,count,matches:[{index,page,line_index,box:{x0,y0,x1,y1},matched_text, lines_before?,lines_after?}]}. Fuzzy mode marks the text header (fuzzy), adds Edit Distance: and
Matched Words: lines, and adds fuzzy, matched_words and total_distance to the JSON.
kis bbox snippet
Section titled “kis bbox snippet”kis bbox snippet -s "<start>" -e "<end>" [files...]| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--start | -s | string | — (required) | Starting phrase, included in the output |
--end | -e | string | — (required) | Ending phrase, excluded unless --include-end |
--input | -i | string array | nil | Path to a bounding-box file (repeatable) |
--format | -f | string | text | text or json |
--output | -o | string | "" (stdout) | Output file path |
--case-insensitive | bool | false | Ignore case when matching the two phrases | |
--include-end | bool | false | Include the ending phrase in the output | |
--fuzzy | int | 0 | Max Levenshtein distance per word; 0 is exact | |
--debug | bool | false | Dump phrase-matching diagnostics to the output stream |
kis bbox snippet -s "Invoice" -e "Total" --include-end data/page1.bboxkis bbox snippet -s "TERMS AND CONDITIONS" -e "SIGNATURE" --fuzzy 2 doc.bboxText output is === Snippet (Page A to B) ===, the two phrases, a blank line, then the extracted
lines. -f json emits {start_phrase,end_phrase,start_page,end_page,line_count,text,lines}, where
text is lines joined by newlines.
--debug writes line and page counts, every start- and end-phrase match, a direct case-insensitive
line scan, per-word block listings with their coordinates, and a spatial comparison of the first two
matched blocks — all to the output stream, so do not combine it with -o and a JSON consumer.
kis bbox snippets
Section titled “kis bbox snippets”kis bbox snippets --snip "name|start|end" [--snip ...] [files...]| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--snip | string array | — (required) | "name|start phrase|end phrase" (repeatable) | |
--input | -i | string array | nil | Path to a bounding-box file (repeatable) |
--output | -o | string | "" (stdout) | Output file path |
--case-insensitive | bool | false | Ignore case for every snippet | |
--include-end | bool | false | Include the ending phrase for every snippet | |
--fuzzy | int | 0 | Max Levenshtein distance per word; 0 is exact |
Each --snip value is split on the first two pipes, every part is whitespace-trimmed, and none may
be empty. Output is always a single JSON object mapping snippet name to extracted text — there is no
format flag.
kis bbox snippets --snip "hdr|Invoice Number|Total" data/page1.bboxkis bbox snippets --snip "header|Invoice|Total" --snip "footer|Terms|END" -i pages/page1.bbox{ "hdr": "Invoice Number INV-42"}A snippet that is not found maps to "" and the command still exits 0.
kis hocr2bbox
Section titled “kis hocr2bbox”kis hocr2bbox -i <file.hocr|dir> [flags]Converts hOCR into the .bbox JSON that every other command consumes. Input comes from -i only;
positional arguments are ignored without a warning.
| Flag | Short | Type | Default | Meaning |
|---|---|---|---|---|
--input | -i | string | "" | hOCR file, or a directory of them |
--output | -o | string | "" | Output file (single input) or directory (directory input) |
--workers | -w | int | 4 | Parallel conversions, directory mode only |
--clean | bool | false | OCR text cleanup: normalise unicode, fix quotes and dashes, drop garbage characters | |
--clean-form | bool | false | Form-aware cleanup that preserves and normalises checkbox and radio indicators | |
--verbose | -v | bool | false | Log each parser warning with its type, element, text and context |
kis hocr2bbox -i pages/scan1.hocr --cleankis hocr2bbox -i pages/ -o bbox/ -w 8 --clean-form -vOutput is one pretty-printed .bbox file per input, named after the input basename with the
extension replaced. With no -o it lands beside the input. Directory mode globs *.hocr
non-recursively. --clean-form takes precedence when both cleanup flags are given.
The produced document, abridged to one word — hOCR line and paragraph grouping is carried through as
lines and paragraphs arrays beside words on each page:
{ "pages": [ { "number": 1, "width": 1224, "height": 1584, "words": [ { "text": "Invoice", "box": { "x0": 100, "y0": 100, "x1": 260, "y1": 140 }, "confidence": 0.96, "page": 1, "line_id": 1 } ] } ]}--input is not marked required. Omitting it fails with stat : no such file or directory — note
the empty path — rather than a required-flag message. A directory containing no *.hocr files logs a
warning and exits 0, which at the default log level looks like a silent success; add -l info to see
it.
The history and audit sidecar
Section titled “The history and audit sidecar”Every rule-running command writes <basename>-hist-audit.json holding the rule-by-rule history of
value changes and the audit log. --history and --audit only control whether the same data is also
printed. The engine logs an executed entry for every rule that fires, so any execution in which a
single rule matched produces a sidecar; an execution where nothing matched produces none.
kis ocr doc writes one sidecar, named after the first resolved prefix.
{ "history": [ { "rule_id": "ClassifyStatement", "key": "document_type", "value": "BANK_STATEMENT" } ], "audit": [ { "rule_id": "ClassifyStatement", "message": "executed" }, { "rule_id": "ClassifyStatement", "message": "header matched" } ]}Exit codes and errors
Section titled “Exit codes and errors”Every command exits non-zero on failure. The rule-running commands print a per-input line, continue with the remaining inputs, print the count, then exit 1 if anything failed — partial success is still exit 1.
ERROR: /work/pages/page3.json: executing rules on /work/pages/page3.json: executing ruleset rules: evaluating expression in rule 'ClassifyStatement' the when raised an error. got non existent key headerProcessed 2/3 file(s) successfully1 file(s) failed to processRule-evaluation errors arrive fully wrapped like that: the CLI’s per-input context, then
executing ruleset <name>:, then the engine’s own message. Read the tail first — it names the rule
and the thing it could not resolve.
kis rules prints those ERROR: lines to stdout; kis ocr page prints its equivalent to stderr. A
script redirecting only one stream sees different things from the two commands.
kis propagates the plugin’s exit code verbatim, forwards SIGINT, SIGTERM and SIGHUP to it,
and reports a signal-terminated plugin as 128+N. Usage text is suppressed on error at every level,
so a failing command prints only its error line.
| Message | Cause |
|---|---|
Error: '<command>' is not installed. | The rules plugin is not on any search path |
required flag(s) "rules" not set | -r omitted; same shape for anchor, phrase, start, end, snip |
flag needs an argument: --fuzzy | --fuzzy with no value on bbox snippet / bbox snippets |
no files matched pattern <dir>/<glob> | kis rules found nothing — a hard error, not a no-op |
no prefixes resolved (...) | kis ocr resolved zero pairs; usually every .json lacked its .bbox |
at least one input file is required (use positional args or -i flag) | A kis bbox subcommand got neither -i nor a file |
invalid var format "<v>": expected key=value | A -v entry with no = |
invalid fact specification "<spec>": key and filepath must not be empty | A -f entry like =path or key= |
invalid bbox specification "<spec>": key and filepath must not be empty | A -b entry like =path or key= |
invalid snippet definition "<s>": expected "name|start phrase|end phrase" | A --snip value that did not split into three non-empty parts |
invalid --skip-pattern "<pat>": <err> | A --skip-pattern that is not a valid glob |
stat : no such file or directory | kis hocr2bbox run without -i |
... the when raised an error. got non existent key <fact> | A rule read a fact the input did not supply |
Header validation failed: missing headers: <list> (found: <list>) | A bbox table -H value is absent |
Header validation failed: table has no headers | bbox table -H on a table with no detected header row |
Rule-evaluation failures surface here too. A missing fact key, a wrong document name or a bad function call aborts the whole execution for that input; see Troubleshooting.
Things that behave differently between commands
Section titled “Things that behave differently between commands”| Behaviour | kis rules | kis ocr page | kis ocr doc |
|---|---|---|---|
-o writes on its own | no, needs --update | yes | yes |
-o is a | directory | directory | file |
--update | writes in place, or results-only into a different -o | ignored when -o is set | not applicable |
| Recursion flag for rule files | -R / --recursive | --recursive-rules | --recursive-rules |
--workers | yes, default 1 | yes, default 1 | no |
--schema / --schemas | no | yes | yes |
Skips *-hist-audit.json | no | yes | yes |
| Per-input errors go to | stdout | stderr | n/a |
Input discovery is a single non-recursive glob everywhere. -R and --recursive-rules affect rule
file discovery only.
kis ocr silently drops directory-glob and file-path inputs whose .bbox sidecar is missing. A bare
prefix skips that check and errors loudly later, at load time, with
reading <prefix>.json: open <prefix>.json: no such file or directory. So a mistyped .json path
vanishes and shows up as no prefixes resolved (...), while a mistyped bare prefix names itself.
Continue with
Section titled “Continue with”- Quickstart — the shortest path from an hOCR file to a rule result.
- Writing rules — rule anatomy, salience and what actually compiles.
- Extraction — fields, checkboxes and schema-driven extraction.
- Rules over documents — the
bboxnamespace a rule calls. - Running the service —
rules.svc, the execute-rule route, tenancy headers and how rule sets arrive. - Error reference — external error codes.