Skip to content

Strict mode

By default binder is never-reject: advisories are reported but exit 0. --strict opts a single run into promoting advisories to gating findings (exit 1), so CI can fail the build on conditions that are informational locally. Each command promotes its own advisory set, listed in the table below. The read-boundary normalization advisory is carved out of those sets: it is reported and does not gate, on enrich or on convert. On a run that reports, the flag changes only the exit code — the report (prose or JSON) is byte-identical with and without the flag — and in no case does it affect any other run.

The per-command contract:

Command --strict gates (exit 1) on Always gates, regardless
validate trust advisories (malformed trust, actor-convention, date-shape warnings) spec §11 hard non-conformance (unparseable frontmatter, missing/empty type)
review any review finding: orphans, stale concepts, unresolved links, unparsed-frontmatter recoveries —
lint any lint finding: broken links, missing titles, orphans, stale, schema violations. The unquoted colon-space advisory is excluded and never gates (see below) —
convert unresolved links, recovery warnings, or non-conformant --status-map status values — (a clean run is exit 0 even under --strict)
enrich skipped (unparseable-frontmatter) files, preserve-or-advise findings, or non-conformant --status-map status values. The read-boundary normalization advisory is excluded and never gates (see below) — (a clean run is exit 0 even under --strict)
infer any warning or inference failure (in practice, Gemini-tier warnings — the deterministic tiers do not warn) —

The read-boundary normalization advisory never gates. When enrich strips a leading UTF-8 BOM or translates a lone CR before recognising the frontmatter (#124), it reports that on two channels, neither of them optional: an advisory: line in the prose report, and in --json a per-file normalized signal plus a top-level result.normalizations entry. That entry discloses what binder did to the input; it is not a finding about the corpus, so enrich keeps it out of the findings count and --strict does not escalate it (#154). A run whose only finding is that advisory exits 0 with or without the flag. A skipped file or a preserve-or-advise warning in the same run still exits 1 under --strict, and the advisory contributes nothing to that count. result.normalizations is additive to binder.report/v1 (the schema string is unbumped) and is omitted when nothing was normalized. convert normalizes at the same read boundary and reports its own read-boundary advisory, which does not gate either; see the convert row above for what convert --strict does gate on. Bound 6 of Residual bounds under enrich covers what the normalization does to the bytes.

The unquoted colon-space advisory never gates either. When lint reports a frontmatter key whose unquoted plain-scalar value contains a colon-space (#93) it names the key to quote in the prose report and in --json under result.colon_space_scalars, but keeps it out of the findings count, so --strict does not escalate it. The reason is not squeamishness about a new rule, and it is not a claim about YAML’s quoting rules: a colon-space can appear in plenty of documents that parse perfectly well, for instance inside a block scalar, where it is ordinary text and not a key at all. The guarantee comes from the wiring instead. The advisory is derived only for a file the codec could not parse — convert computes it from the same recovered flag that produces the invalid frontmatter schema violation, so the file carrying an advisory is always already reported by that violation, and that violation does gate under --strict. Counting the advisory too would gate twice on one defect. Nothing goes unreported; the advisory only says which key to quote in a file already flagged. Removing that gate would not be a simplification: it is the whole of the never-gates guarantee, and without it the rule can name a “key” in a cleanly-parsing file with no violation to subsume it. result.colon_space_scalars is additive to binder.report/v1 (the schema string is unbumped).

The --status-map vocabulary gate is the one that fires before anything is written: convert --strict exits 1 without creating the output directory, and enrich --strict exits 1 without touching a single source file. Adding --canonicalize-status resolves a known alias and the run returns to exit 0. See Status vocabulary and --canonicalize-status.

--strict is available on validate, review, lint, convert, enrich, and infer. A clean run stays exit 0 even with --strict set, so the flag is safe to leave on permanently in CI. index, graph, and config have no advisory surface and do not take it.

Terminal window
# Fail CI on any unresolved link or recovered file, not just spec violations
SOURCE_DATE_EPOCH=1700000000 binder convert docs/ -o build/bundle --strict
binder validate build/bundle --strict
binder review build/bundle --strict
# Fail CI on source-corpus health before conversion
binder lint docs/ --strict