Skip to main content

Reading the verdict

Per-lane counts, how many flags were suppressed, and the exit code. Every flag above it names a rule, a target, a copyable id, and a plain-English rationale.

Exit 1 with zero flags

This means a required lane didn’t run. schema and spec_conflict are required. If you filtered one out with --source, or it errored, conformance can’t certify and fails closed — even with nothing to report. Check the lanes line:
If a lane says did_not_run, either you excluded it or it crashed. With --json, lane_errors names the error type.
This is deliberate. “We didn’t check” is never a pass.

Exit 2

A usage or input error, not a conformance failure. Causes:
  • The package directory doesn’t exist. Check the path — conform takes the directory containing manifest.yaml, not the manifest itself.
  • An invalid flag value, such as an unrecognized --fail-on.
  • An unknown lane in --source.
  • An unreadable allowlist file.
  • A package the engine refused to read: oversized, containing symlinks, or malformed.

Schema flags

Schema is authoritative and has no false positives by construction. A schema flag is a real, mechanical problem: a missing required field, a bad enum, an out-of-range value, a dangling file reference, an unparseable JSONPath. Fix the package and re-run. Each fix drops a flag.

Spec-conflict flags

These flag known contradictions or stale residue in the spec itself, surfaced so canonical examples aren’t mistaken for a clean oracle. They default to warning, but a rule can override to error — the lifecycle conflict is one such override.
Remove the field the flag names. Lifecycle state is managed by the platform, not declared by you.

An ignore stopped working

Two likely causes. The entry expired. An allowlist entry with an expires date at or before today stops suppressing, so the flag resurfaces. That’s intentional — it forces a periodic re-decision. Renew or remove the date:
The flag’s identity changed. A flag id is sha256(rule_id + artifact_target + violation_class). Rephrasing a rationale doesn’t change it, but a change to the rule, the target, or the violation class does. Re-run with --show-ignored to see what is actually suppressed, and compare against the new flag’s fields.

Too many flags on an existing package

Snapshot the current state so only new drift surfaces afterward:
This writes one entry per flag and exits without running the verdict. Re-baselining is idempotent and never drops prior acknowledgements.

Making flags advisory

All flags become advisory and the run exits 0 regardless of severity. A degraded required lane still forces 1. Use this while adopting conformance, not as a permanent setting — it turns off the gate.

The spec version changed

A spec pack is identified by a content hash, like v05@84aa360f…. When the vendored spec is refreshed, the hash changes and acknowledgements are re-evaluated against the new content. Conformance always checks against an explicit version:
Checking a v0.5 package against a future version is a deliberate migration exercise, never a silent drift.

In CI

The command exits with the report’s own code, so no wrapper is needed. Diagnostics go to stderr, so the JSON on stdout stays parseable.

See also