Reports and exit codes

Every command ends with a report. Read three things in order: the outcome (did it pass?), the scope (what was examined) and then the findings, errors first. inspect covers sources and bibliography only; prepare also covers the build, PDF preservation and the fresh ZIP rebuild.

The terminal summary

Rich styles the outcome, groups findings and aligns artifacts without relying on color to convey status. Live terminals show the current stage and elapsed time on stderr. Redirected output uses plain stage lines; --quiet suppresses progress. NO_COLOR disables color. JSON, compact and selected submission-text fields remain suitable for scripts.

This run passed with one advisory, a TODO marker: the bundle was written, but the warning needs a human decision.

Passed with advisories — selected preparation checks, visual/text preservation and fresh ZIP rebuild
0 errors, 1 warning, 0 incomplete, 4 not applicable, 23 passed results
Document: main.tex

TEX001  Unfinished text markers  [WARNING / failed]
  Where: sections/results.tex:4
  Possible unfinished editing or placeholder text: 'TODO'.
  Next: Finish or remove the marked draft text after reviewing its context.
sources: /private/tmp/submission-advisory-final/sources
archive: /private/tmp/submission-advisory-final/submission.zip
pdf: /private/tmp/submission-advisory-final/manuscript.pdf
report: /private/tmp/submission-advisory-final/report.json

Not checked (needs your settings): anonymity, page limit, ZIP size limit, forbidden packages, strict font embedding, image resolution, 93 other opt-in checks. Set them in fledge.toml (start with fledge init --preset anonymous-review|arxiv|camera-ready); see https://nicolasschuler.github.io/fledge/configuration.html

Explain a check: fledge rule CODE

The first line gives the outcome and scope, the second the counts. Each finding then shows its code and name, [SEVERITY / status], where it is, what was observed and the next step. A finding repeated in several stages is shown once with all stage names in brackets; the counts line counts it once. Passed results and scope notes are counted but listed only with --show-passed. The example above omits the terminal’s decorative borders and file summary.

When a failed step prevents later checks, one line per failed step names the checks that did not run, as in the blocked example. The final Not checked line lists opt-in areas that did not run because they need your settings, or because selection turned them off. Without a settings file it suggests starting from a preset; with one, it names that file as the place to add them. This line appears in terminal output only; JSON reports list the same areas in execution.not_checked.

What is in the submission?

Preparation reports summarize included and excluded files, filename changes, ZIP size and the largest compressed entries. Add --show-files to list every entry and its selection reason:

fledge prepare paper --output submission --show-files
fledge prepare paper --dry-run --show-files

Each document has its own inventory. A verified inventory uses the exact ZIP that was rebuilt, including each entry’s original and compressed sizes. ZIP overhead is reported separately from compressed file data. prepared means files were assembled but final verification has not passed. proposed marks a dry-run or initial selection; incomplete means dependency selection failed. These labels never turn a blocked run into a released submission. Unmeasured sizes are shown as such, including excluded archive metadata that was not imported.

JSON stores these records in package_contents; HTML always includes the full table. Both include original source paths, final paths and selection reasons.

Exit codes

Exit

Outcome

Bundle written?

Meaning

0

passed

Yes

Everything in the stated scope passed

0

planned

No

A --dry-run plan; nothing was verified

1

passed_with_advisories

Yes

Required checks passed; warnings need review

2

accepted_exceptions

Yes

Passed only because of reviewed exceptions in your configuration

3

blocked

No

A required check failed or lacked evidence

4

error

No

Input, configuration, execution or report-writing problem, or an internal error

64

none

No

Invalid command-line syntax; no report

130

cancelled

No

Interrupted

The Bundle written? column applies to prepare --output; inspect and check never write a bundle.

An unexpected failure inside Fledge never ends with 0, 1 or 2: it exits with 4 and prints one line on stderr. The JSON report then holds a finding with the rule execution.internal that records the error_type and the innermost frames (file.py:line in function, without directories). Pass --debug or set FLEDGE_DEBUG=1 to print the full traceback when you report the defect. A crash while printing or saving the report also exits with 4.

A defect inside one check does not stop the others. The report keeps their results and adds an execution.task finding for the failed check, whose details.traceback lists the innermost frames, and the run exits with 4 rather than 3. A check that fails because of your input or machine, such as an unreadable file, blocks the run with 3 instead.

Why advisories exit with 1. A TODO marker or an unused bibliography entry does not stop the release, but nobody has looked at it yet. A nonzero code makes scripts and CI notice instead of shipping silently. Once you have reviewed the warnings, the bundle is ready to use.

Why accepted exceptions exit with 2. An accepted exception means a check failed and your configuration says that is acceptable, with a written reason. A separate code lets automation tell “clean” from “clean because we decided so”. The original failure stays in the report.

In CI, treat 0 as success and 3, 4, 64 and 130 as failure. Choose a policy for the others: accept 1 and surface its annotations (--output-format ci), or fail on it if you want zero warnings; accept 2 only when the exceptions are committed in the repository’s fledge.toml. For example, to accept 0, 1 and 2:

status=0
fledge check paper --output-format ci --quiet || status=$?
[ "$status" -le 2 ] || exit "$status"

For automation that needs more than the exit code, read command and outcome from the JSON report. An internal error still writes the report, as an execution.internal finding with exit 4.

The JSON report

prepare writes report.json with a successful output; --json-report FILE (also spelled --report) saves the same JSON for any run, including a blocked one. This excerpt is from the blocked run in the quick start, with most findings, settings and tool details removed:

{
  "schema_version": 2,
  "command": "prepare",
  "outcome": "blocked",
  "scope": "selected source, bibliography, privacy, isolated build and PDF checks",
  "main": "main.tex",
  "findings": [
    {
      "rule": "bibliography.citation_coverage",
      "message": "Citation key 'knuth1948' has no entry in this root's inspected resources.",
      "severity": "error",
      "status": "failed",
      "path": "sections/results.tex",
      "line": 5,
      "evidence_kind": "derived",
      "incomplete": false,
      "details": {
        "key": "knuth1948",
        "document": "main.tex",
        "resources": [
          "references/library.bib"
        ],
        "uncertainty": [],
        "stage": "bibliography coverage and fields"
      },
      "code": "BIB101",
      "next_step": "Correct the citation key or declared bibliography resource, then compile to verify the rendered citations. Resolve reported source uncertainty before claiming coverage."
    }
  ],
  "changes": [],
  "artifacts": {},
  "execution": {
    "config_path": null,
    "preset": null,
    "check_selection": {
      "select": [
        "ALL"
      ],
      "ignore": []
    },
    "not_checked": [
      {
        "area": "page_limit",
        "label": "page limit",
        "codes": [
          "PDF001"
        ],
        "settings": [
          "max_pages"
        ]
      }
    ]
  }
}

Field

What it holds

schema_version

The report format version, currently 2

outcome, scope

The result and what it covers

findings

Every result, including passed ones and scope notes

changes

Proposed or applied edits, with diffs

settings

The effective settings after preset, file and command line, under their current names (apply_formatting, rendered_pdf_artwork and included_figure_artwork replace format, pdf_artwork and figure_artwork)

tools

Versions and paths of the tools used

stages

Each build and verification step with its status and elapsed seconds

artifacts

Paths of the published output, as written; empty when blocked

package_contents

Per-document inventory, verification status, selection reasons and measured file/ZIP sizes

execution

Configuration file, preset, check selection, opt-in checks that did not run (not_checked), resource use and timing

Every other path in a report, such as the settings file, a reference PDF or a tool location, shows your home directory as ~ and the system temporary directory as <tmp>, so a report can be shared without revealing a user name. Paths inside the project stay relative, and artifacts keeps the real location of the files Fledge wrote.

A finding’s code is null for operational results such as build.failed: results that describe the run or the tool environment rather than the manuscript. They cannot be selected or ignored and are always reported. Its rule always holds a descriptive name. evidence_kind says how directly the evidence supports the result (direct, derived or heuristic), and next_step gives the suggested action when one applies. incomplete is true when the check’s evidence was partial, unavailable or bounded, for example an unreadable file, an unmeasured page or a capped list of matches. Unlike the incomplete count of the terminal summary, which counts results that reached no decision, this flag can also mark a confirmed failure; such a failure can be neither accepted nor suppressed. A failed build’s finding carries the last 60 lines of the TeX log (at most 8000 characters) in details.log_tail. The glossary defines severity, status and the other terms.

schema_version increases only when a field is removed, renamed or changes meaning. New fields can appear within a version, so ignore fields you do not recognize. The JSON Schema describes the stable fields: the top-level layout, findings, changes and the allowed commands, outcomes, severities and statuses. The contents of settings, tools, execution, stages, package_contents and finding details are descriptive and may grow.

The JSON of fledge rules, fledge rule CODE and fledge submission-text has its own schema_version, currently 1, with the same rule: it increases only when a field is removed, renamed or changes meaning. fledge rules --json lists the checks under rules; each check says whether it is mandatory (check selection never removes its findings) and whether it is reviewable (an explicit review decision may suppress or accept it).

Version 2 renamed the finding fields evidence to evidence_kind and suggestion to next_step, and added incomplete. Hyphenated rule names such as source-edit-marker became dotted names such as source.edit_marker, and settings records format, pdf_artwork and figure_artwork as apply_formatting, rendered_pdf_artwork and included_figure_artwork. In fledge doctor reports, a rejected request is now execution.request and an internal error execution.internal; they were configuration.invalid and execution.error.

Other formats

fledge rule TEX001
fledge check /path/to/paper --json-report report.json
fledge check /path/to/paper --html-report report.html
fledge check /path/to/paper --output-format compact --quiet

HTML is a self-contained offline page with source diffs and, when PDF comparisons find differences, page previews. It follows the light or dark setting of the reader’s browser, prints cleanly, and its title names the command and document. Compact output writes one line per finding, which suits pasting into an AI agent; checks that did not run after a failed step appear on lines starting with not run:. HTML and CI output also show a finding repeated in several stages once, but have no Not checked line. Reports redact known credential patterns but do not sanitize your sources, so read a report before sharing it. The workflow reference describes every format and the redaction rules, and preparation options describes accepted exceptions and suppressions.

Visual PDF differences

Request HTML during the run to retain affected PDF pages:

fledge prepare paper --output submission --html-report review.html
fledge pdf check revised.pdf --reference-pdf original.pdf --html-report review.html

The report shows before/after pages and an expandable difference overlay, with navigation between affected pages. Text-only differences, added or removed pages and changed page dimensions are labeled. The original images remain the reference for interpreting an overlay. Previews are available in a blocked report even when no submission ZIP is released.

Capture is limited to eight page pairs and 12 MiB of PNG data across the whole run. The first affected pages in document/stage order receive that budget. Omitted, partial and unavailable previews are explicit; their absence does not change the comparison findings. HTML adds bounded rendering work and serializes comparisons and document workflows where needed for stable allocation. Runs without HTML do not capture these images.

The HTML embeds its images and needs no server or external resources. JSON contains descriptors in execution.pdf_previews, not image bytes. Re-rendering JSON alone cannot recover previews. Page images contain manuscript content and are not credential-redacted; inspect the report before sharing it.