Skip to content

Compat report schema reference

This page is generated from the machine schema, property by property, so it cannot drift from it. For the narrative version — how the verdict is derived, what the warning-code ranges mean, jq recipes for gating CI — read the compatibility report guide.

FieldValue
Dialecthttps://json-schema.org/draft/2020-12/schema
$idhttps://rendlio.com/schemas/compat-report/v1.json
Served at/schemas/compat-report/v1.json — byte-identical to the vendored file
TitleRendlio Compatibility Report
Root typeobject, additionalProperties: false
Top-level properties13, of which 13 required
Vendored pinengine commit 8f2013b, sha256 18e09a291424

Family scope: the envelope core (schemaVersion, engine, input, options, mode, result, warnings, timings) is shared by every Rendlio engine; the remaining sections are grid-engine payload. This schema is never extended to carry another format.

That is a normative $comment in the schema itself, not a note added here: compat-report.v1 never mutates. A future engine that needs a different envelope gets a new $id and a sibling schema, so a validator pinned to v1 keeps working.

PropertyTypeRequiredDescription
schemaVersionstringyesVersion of this report schema, semver-like 1.x. Additive optional fields bump the minor; anything else bumps the major and gets a new schema URL. (pattern ^1\.[0-9]+$)
engineobjectyesIdentity of the build that produced the report.
inputobjectyesIdentity of the bytes that were read, so a report can be tied back to an exact input.
optionsobjectyesCanonicalized effective options — an exact echo of the CLI flag values including defaults, plus licenseMode ("licensed:<tier>" or "evaluation"). No other licence data ever appears in a report. Deliberately unconstrained so a new flag does not need a schema change.
mode"convert" | "diagnose"yesWhich mode produced the report. diagnose never writes documents and additionally records rendered entries.
resultobjectyesThe run’s verdict and the process exit code, always in agreement.
pagesobjectyesOutput pagination.
sheetsarray of objectyesOne entry per sheet in the workbook, in workbook order.
featuresarray of objectyesThe heart of the report: one entry per (feature, status) pair, enforcing the engine-wide rule that nothing is ever silently approximated. In convert mode only deviations are listed, so an empty array means nothing deviated; diagnose additionally lists rendered entries.
fontsobjectyesFont resolution outcome. Substitutions are called out because they shift column widths and line breaks.
formulasobjectyesFormula-cell accounting.
warningsarray of objectyesCoded warnings. Codes are owned by engine modules in fixed ranges, listed in the guide.
timingsobjectyesWall-clock milliseconds per phase. Reported for observability; not a determinism guarantee.

Version of this report schema, semver-like 1.x. Additive optional fields bump the minor; anything else bumps the major and gets a new schema URL.

Type string · required · pattern ^1\.[0-9]+$.

Identity of the build that produced the report.

Type object · required · additionalProperties: false.

FieldTypeRequiredDescription
name"Rendlio" (const)yesProducing engine. Always the same value — a report is never emitted by anything else.
versionstringyesEngine semver, as printed by rendlio version.
releaseDatestringyesISO date of the build. Licence maintenance windows are compared against this, not against the clock. (format date)

Identity of the bytes that were read, so a report can be tied back to an exact input.

Type object · required · additionalProperties: false.

FieldTypeRequiredDescription
sha256stringyesSHA-256 of the input bytes, lower-case hex. (pattern ^[0-9a-f]{64}$)
sizeBytesintegeryesLength of the input in bytes. (minimum 0)
fileNamestringnoOriginal file name. Omitted when the input arrived on stdin.

Canonicalized effective options — an exact echo of the CLI flag values including defaults, plus licenseMode ("licensed:<tier>" or "evaluation"). No other licence data ever appears in a report. Deliberately unconstrained so a new flag does not need a schema change.

Type object · required · free-form — no constrained properties.

Which mode produced the report. diagnose never writes documents and additionally records rendered entries.

Type "convert" | "diagnose" · required.

mode values — all 2, exhaustive:

ValueMeaning
"convert"A conversion run. Writes documents; the report lists deviations only.
"diagnose"Analysis only. Writes no documents and additionally records rendered entries.

The run’s verdict and the process exit code, always in agreement.

Type object · required · additionalProperties: false.

FieldTypeRequiredDescription
status"success" | "warnings" | "unsupported-content" | "invalid-input" | "resource-limit" | "error"yesVerdict, derived by the ladder documented in the compatibility report guide.
exitCodeintegeryesProcess exit code, matching status: 0 success, 1 warnings, 2 unsupported content, 3 invalid input, 4 resource limit, 5 internal error. (minimum 0, maximum 5)

result.status values — all 6, exhaustive:

ValueMeaning
"success"Faithful throughout — no warnings, nothing approximated.
"warnings"Converted, with at least one warning or one approximated feature.
"unsupported-content"Converted, but at least one feature was unsupported.
"invalid-input"Not a workbook this engine can read — wrong format, or encrypted.
"resource-limit"A limit fired (timeout, memory, size). Partial outputs are deleted.
"error"Internal fault. Report the input and this report.

Output pagination.

Type object · required · additionalProperties: false.

FieldTypeRequiredDescription
countintegeryesRendered page count. 0 for diagnose and for failures. (minimum 0)

One entry per sheet in the workbook, in workbook order.

Type array of object · required · additionalProperties: false.

Item fieldTypeRequiredDescription
namestringyesSheet name as stored in the workbook.
indexintegeryesZero-based position of the sheet in the workbook. (minimum 0)
printedbooleanyesWhether the sheet contributed pages. false = hidden, or entirely outside the print area.

The heart of the report: one entry per (feature, status) pair, enforcing the engine-wide rule that nothing is ever silently approximated. In convert mode only deviations are listed, so an empty array means nothing deviated; diagnose additionally lists rendered entries.

Type array of object · required · additionalProperties: false.

Item fieldTypeRequiredDescription
idstringyesStable feature identifier F-<AREA>-<slug>, where <AREA> is one of PARSE, STY, NUM, LAY, CF, CHT, IMG, TXT, PDF, PNG, REC, LIC, SEC. Identifiers are never repurposed. (pattern ^F-(PARSE|STY|NUM|LAY|CF|CHT|IMG|TXT|PDF|PNG|REC|LIC|SEC)-[a-z0-9-]+$)
status"rendered" | "approximated" | "unsupported" | "skipped"yesWhat happened to this feature — see the value table below.
countintegeryesOccurrences of this (feature, status) pair. Always the real total, even when locations is truncated. (minimum 1)
locationsarray of locationnoWhere the occurrences are. Capped; count keeps the real total. (at most 20 items)
locationsTruncatedbooleannotrue when more occurrences existed than locations could list.
detailstringnoPlain-language statement of the rule that applied. Static template text plus counts and locations only — never cell contents, so a diagnose report is safe to share.

features[].status values — all 4, exhaustive:

ValueMeaning
"rendered"Faithful per the specification rule for this feature. Recorded in diagnose mode only.
"approximated"Rendered, but a documented deviation applies — detail says which.
"unsupported"Present in the file, not rendered; the space it would occupy follows the rule for that feature.
"skipped"Present but intentionally outside conversion semantics — not a fidelity gap.

Font resolution outcome. Substitutions are called out because they shift column widths and line breaks.

Type object · required · additionalProperties: false.

FieldTypeRequiredDescription
substitutionsarray of objectyesEvery family that was requested but not used, with what replaced it.
missingarray of stringyesRequested families with no substitute rule at all.

Type array of object · additionalProperties: false.

Item fieldTypeRequiredDescription
requestedstringyesFamily name asked for by the workbook.
usedstringyesFamily actually rendered with.
reason"metric-substitute" | "fallback" | "missing-default"yesWhy the substitution happened — see the value table below.

fonts.substitutions[].reason values — all 3, exhaustive:

ValueMeaning
"metric-substitute"Replaced by a metrically compatible family; layout is preserved.
"fallback"Replaced by a generic fallback; glyph shapes and metrics differ.
"missing-default"The workbook’s default family was unavailable — expect column widths and line breaks to shift.

Formula-cell accounting.

Type object · required · additionalProperties: false.

FieldTypeRequiredDescription
cellsTotalintegeryesNumber of formula cells in the workbook. (minimum 0)
cachedMissingintegeryesFormula cells carrying no cached value. In off recalc mode these render empty. (minimum 0)
recalcMode"off" | "strict-v1"yesRecalculation mode in force — see the value table below.
closureSizeinteger | nullnoSize of the evaluation closure when strict-v1 evaluated or refused; null otherwise. (minimum 0)

formulas.recalcMode values — all 2, exhaustive:

ValueMeaning
"off"Cached formula values are rendered as stored. Cells with no cached value render empty.
"strict-v1"The engine evaluated the formula closure itself, or refused and said so.

Coded warnings. Codes are owned by engine modules in fixed ranges, listed in the guide.

Type array of object · required · additionalProperties: false.

Item fieldTypeRequiredDescription
codestringyesWarning code, W followed by four digits. (pattern ^W[0-9]{4}$)
severity"info" | "warn" | "error"yesHow much the warning matters — see the value table below.
messagestringyesStatic template text plus counts and locations only — never cell contents.
locationlocation objectnoWhere the warning applies. Omitted, or all-null, for a document-scope warning.

warnings[].severity values — all 3, exhaustive:

ValueMeaning
"info"Worth knowing; nothing to act on.
"warn"Output may differ from the workbook — check the named location.
"error"Something did not work; read result.status for the verdict.

Wall-clock milliseconds per phase. Reported for observability; not a determinism guarantee.

Type object · required · additionalProperties: false.

FieldTypeRequiredDescription
parseMsnumberyesTime spent reading and parsing the workbook. (minimum 0)
layoutMsnumberyesTime spent paginating and laying out. (minimum 0)
renderMsnumberyesTime spent producing output bytes. (minimum 0)
totalMsnumberyesTotal wall-clock time for the run. (minimum 0)

A place in the workbook. At least one property must be present; each may be null when it does not apply.

Type object · at least 1 property present · additionalProperties: false.

Referenced by features[].locations[], warnings[].location.

FieldTypeRequiredDescription
sheetstring | nullnoSheet name, or null for a workbook-scope location.
refstring | nullnoA1 cell or range — "B7", "A1:C30" — or null.
objectIdstring | nullnoDrawing/chart part-relative id, or null.

All 7 closed value sets in v1, read straight out of the schema. Nothing outside these lists is valid.

PathKindValues
engine.nameconst"Rendlio"
modeenum"convert" | "diagnose"
result.statusenum"success" | "warnings" | "unsupported-content" | "invalid-input" | "resource-limit" | "error"
features[].statusenum"rendered" | "approximated" | "unsupported" | "skipped"
fonts.substitutions[].reasonenum"metric-substitute" | "fallback" | "missing-default"
formulas.recalcModeenum"off" | "strict-v1"
warnings[].severityenum"info" | "warn" | "error"

A complete report — every top-level property, and every optional field the schema allows. The generator validates it against the schema with ajv before writing this page, so it is a report the schema accepts. Real reports are plain JSON; the // comments are annotation only.

{
"schemaVersion": "1.0",
"engine": {
"name": "Rendlio", // always "Rendlio"
"version": "0.3.1",
"releaseDate": "2026-10-02"
},
"input": {
"sha256": "fd646a748c6397ce85167b4763e8f5ee037caac1c33318c48d6955ae01837993", // of the input bytes, not of the output
"sizeBytes": 183422,
"fileName": "quarterly-close.xlsx" // optional
},
"options": { // abridged; the real echo carries every effective flag
"report": "-",
"recalc": "off",
"sheets": "all",
"licenseMode": "evaluation" // the only licence data a report ever carries
},
"mode": "diagnose", // "convert" | "diagnose"
"result": {
"status": "unsupported-content", // one of 6 — see the `result.status` values table
"exitCode": 2 // always agrees with status
},
"pages": {
"count": 0 // 0 for diagnose and for failures
},
"sheets": [
{
"name": "Summary",
"index": 0,
"printed": true // false = hidden or outside the print area
},
{
"name": "Data",
"index": 1,
"printed": true
},
{
"name": "Archive",
"index": 2,
"printed": false
}
],
"features": [ // convert mode lists deviations only; [] = nothing deviated
{
"id": "F-NUM-number-format",
"status": "rendered", // one of 4 — see the `features[].status` values table
"count": 41, // real total, even when locations is truncated
"detail": "Excel display strings reproduced with the locale pinned to the workbook setting." // optional
},
{
"id": "F-STY-cell-fill",
"status": "rendered",
"count": 218,
"detail": "Solid, pattern, and gradient fills painted from the workbook theme."
},
{
"id": "F-LAY-merged-cell",
"status": "rendered",
"count": 12,
"detail": "Merged ranges drawn as a single cell with the anchor cell's alignment."
},
{
"id": "F-CF-time-period",
"status": "approximated",
"count": 3,
"locations": [ // optional
{
"sheet": "Summary",
"ref": "B4:B31"
},
{
"sheet": "Data",
"ref": "H2:H480"
}
],
"detail": "timePeriod rules are evaluated against the conversion date, not the workbook's last-open date."
},
{
"id": "F-CHT-3d-surface",
"status": "unsupported",
"count": 2,
"locations": [
{
"sheet": "Summary",
"objectId": "drawing1:chart2"
},
{
"sheet": "Data",
"objectId": "drawing2:chart1"
}
],
"detail": "3-D surface charts are outside the supported chart set; the plot area is rendered empty."
},
{
"id": "F-IMG-vml-extrusion",
"status": "unsupported",
"count": 1,
"locations": [
{
"sheet": "Archive",
"objectId": "vmlDrawing1:shape7"
}
],
"detail": "Legacy VML 3-D extrusion is outside the supported drawing set; the space it occupies is rendered empty."
},
{
"id": "F-SEC-vba-project",
"status": "skipped",
"count": 1,
"detail": "VBA projects are never executed and never rendered; this is not a fidelity gap."
},
{
"id": "F-REC-data-validation",
"status": "skipped",
"count": 27,
"locations": [
{
"sheet": "Data",
"ref": "C2"
},
{
"sheet": "Data",
"ref": "C3"
},
{
"sheet": "Data",
"ref": "C4"
},
{
"sheet": "Data",
"ref": "C5"
},
{
"sheet": "Data",
"ref": "C6"
},
{
"sheet": "Data",
"ref": "C7"
},
{
"sheet": "Data",
"ref": "C8"
},
{
"sheet": "Data",
"ref": "C9"
},
{
"sheet": "Data",
"ref": "C10"
},
{
"sheet": "Data",
"ref": "C11"
},
{
"sheet": "Data",
"ref": "C12"
},
{
"sheet": "Data",
"ref": "C13"
},
{
"sheet": "Data",
"ref": "C14"
},
{
"sheet": "Data",
"ref": "C15"
},
{
"sheet": "Data",
"ref": "C16"
},
{
"sheet": "Data",
"ref": "C17"
},
{
"sheet": "Data",
"ref": "C18"
},
{
"sheet": "Data",
"ref": "C19"
},
{
"sheet": "Data",
"ref": "C20"
},
{
"sheet": "Data",
"ref": "C21"
}
],
"locationsTruncated": true, // optional
"detail": "Data-validation rules have no static representation and are intentionally outside conversion semantics."
}
],
"fonts": {
"substitutions": [
{
"requested": "Calibri",
"used": "Carlito",
"reason": "metric-substitute" // "metric-substitute" | "fallback" | "missing-default"
},
{
"requested": "Wingdings",
"used": "DejaVu Sans",
"reason": "fallback"
},
{
"requested": "Aptos Narrow",
"used": "DejaVu Sans",
"reason": "missing-default"
}
],
"missing": [
"Marlett"
]
},
"formulas": {
"cellsTotal": 4183,
"cachedMissing": 0, // render empty while recalcMode is "off"
"recalcMode": "off", // "off" | "strict-v1"
"closureSize": null // integer once strict-v1 evaluates or refuses · optional
},
"warnings": [
{
"code": "W1011",
"severity": "warn", // "info" | "warn" | "error"
"message": "External workbook link rendered from its cached value; no network refresh was attempted.",
"location": { // all-null = document scope · optional
"sheet": "Summary",
"ref": "E12"
}
},
{
"code": "W2104",
"severity": "info",
"message": "Custom number format approximated to the nearest supported pattern."
},
{
"code": "W5104",
"severity": "warn",
"message": "Requested font is not installed; a metric-compatible substitute was used."
},
{
"code": "W7002",
"severity": "error",
"message": "A page exceeded the PDF media box and was clipped to the print area.",
"location": {
"sheet": "Data"
}
},
{
"code": "W9001",
"severity": "info",
"message": "No licence found; the evaluation watermark was applied to every page."
}
],
"timings": { // wall-clock, not a determinism guarantee
"parseMs": 118.4,
"layoutMs": 96.2,
"renderMs": 0,
"totalMs": 231.7
}
}
Terminal window
curl -sO https://rendlio.com/schemas/compat-report/v1.json
ajv validate --spec=draft2020 -s v1.json -d report.json

The schema is served at its own $id, so that URL is fetchable rather than merely canonical. Within v1 only optional fields are ever added, so a validator pinned to v1 keeps working across engine updates.

View as Markdown