Skip to content

No installed format writes a classification tag, so the multi-tag export rule has nothing to attach to #603

Description

@JArmandoAnaya

Decided 2026-08-15:

Classification exports emit one entry per (image, tag) pair — an image with N tags appears N
times, once per tag.

Found while implementing it: there is nowhere to put the rule. Every installed exporter has an
explicit branch that drops a classification tag.

exporter supported_geometries what it does with a tag
coco {BBOX, POLYGON} _annotation() returns None, row skipped
yolo {BBOX}, degraded {POLYGON} _as_box() returns None, _rows() continues
voc {BBOX}, degraded {POLYGON} _as_box(): "a classification tag: no location, and VOC's <object> is a location"
the five lane formats {POLYLINE} not written
dummy every geometry declares it, writes nothing at all

The only tag-supporting exporter in the repo is a fake inside tests/cli/test_export_commands.py.
Three tests pin today's behaviour: test_a_classification_tag_produces_no_object_at_all (voc),
…_produces_no_row_at_all (yolo), …_makes_the_release_need_consent (coco).

So the rule cannot be violated by code that does not exist. It is really the specification for a
format nobody has written
: an image-classification layout whose content is tags — a folder tree
per class, or a labels.csv.

What it takes

  1. A module under src/visionset/formats/, supported_geometries including
    GeometryType.CLASSIFICATION_TAG, registered in [project.entry-points."visionset.formats"].
  2. One row per (image, tag). This already agrees with the pre-export report, which counts
    annotations rather than images (ReleaseService._compatibility, keyed
    (label_class, geometry)) — a per-image emitter is the one that would disagree with it.
  3. tests/formats/test_report_agreement.py is a hard gate: a new exporter either lands a counter
    there or is declared as one that writes nothing, and
    test_every_installed_exporter_is_accounted_for fails until somebody chooses. Its counters read
    rows back off disk.
  4. The report has no per-image line today, so "how many images were duplicated by multiple tags"
    needs a home if it is wanted.

Worth deciding at pickup: a new format, or a second task file inside coco. The second changes
bytes for existing consumers and breaks the three pinning tests, so it is the more expensive of the
two despite looking smaller.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions