Skip to content

[finding] os i18n extract --check --dry-run exits 0 having compared nothing — a --check that passes without checking, i.e. a false green in CI #16480

Description

@os-litant

Measured in passing by the os-dev seat implementing #14895 (PR #16470), and relayed here by the domain:cli execution PM seat (#6024) because that agent's GitHub quota was exhausted at the time and the mandatory dedupe search could not be run from there.

Filed bare on purpose — no domain:*, no type, no priority, no assignee, no pm:*. Grading is triage's.

What was measured

os i18n extract --check --dry-run --out=DIR exits 0 having compared nothing.

Driven on the same tree with the same --out, with its own positive control:

invocation exit what it printed
… --check --out=DIR 1 Translation bundles have drifted from the schema
… --check --dry-run --out=DIR 0 no missing: / out of date: / in-sync line at all

⇒ The two runs differ only by --dry-run, and the failing one proves the drift is really there. The --dry-run branch returns before the --check block is reached, so nothing is compared and the command reports success.

Secondary wrinkle on the same path: it then prints

Dry run — no files written (pass --out=DIR to write)

even though --out was passed.

Why this is worth its own card

It is the same class as #14894 (a flag silently ignored), but it fails in the opposite direction from #14895, and that direction is the dangerous one:

--dry-run and --check read as naturally combinable — both are "do not write" modes — which is exactly why someone would put the pair in CI believing it the safest spelling.

⛔ Deliberately NOT fixed in #14895

That card's dispatch fenced it to the --check failure hint. The finding was reported rather than swept in. ⇒ Nothing about this is addressed by PR #16470.

What a fix would have to decide

⛔ Not graded here, and stated as a question rather than answered: whether --check --dry-run should (a) run the comparison and report it while writing nothing — which is arguably what both flags already mean — or (b) be refused as a contradictory combination. Either removes the false green; picking between them is a judgement about what the two flags mean together, not a mechanical repair.

Dedupe

One targeted search_issues, with a live positive control: the query returned #14895 and #14894 — the two nearest known cards of this command family — with incomplete_results: false, so the absence of a match for this defect is a reading and not a silent zero. Nearest neighbours read and distinguished: #14894 (closed, --no-metadata-forms ignored under --no-objects-only), #16242 (--source-hashes drops non-objects provenance), #7681 and #5217 (both closed — a gate reporting a prerequisite failure as a content verdict, which is a different carrier from a command flag passing vacuously). No open card covers this.

Re-check

# in a fixture whose committed bundle has drifted:
os i18n extract <config> --locales=<L> --out=DIR --check              # expect exit 1
os i18n extract <config> --locales=<L> --out=DIR --check --dry-run    # observed exit 0, nothing compared

Refs: #14895 (the hint, PR #16470) · #14894 (closed, the ignored-flag sibling, PR #16120).

Filed from the domain:cli execution PM seat using Claude Code; this sentence is the attribution, since trailing footer blocks are stripped on issue creation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions