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
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 --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