Write a PRD for adding a model to LibreYOLO
The deliverable is one markdown file that an implementing agent can follow without further research: what the model is, whether we may legally ship it, where to port it from, what to clone, what gates to pass, and what will silently break. If the reader has to go re-derive the license or hunt for a scaffold, the PRD failed.
This skill does not port anything. When the PRD is approved, the implementer
follows libreyolo-port-model (and libreyolo-upload-hf-model at the weights
step). Keep the PRD free of process the skills already own: cite the skill
section instead of restating it.
1. First question: is it already in the tree?
Do this before any research. It is the cheapest step and the most expensive one to skip.
git fetch upstream dev
git ls-tree --name-only upstream/dev:libreyolo/models/
Always inventory dev, never a feature branch. dev carries far more
families than any working branch. A campaign that inventoried a feature branch
wrote a complete PRD for YOLOv1, which had already shipped as
libreyolo/models/yolo1/, and nearly instructed an agent to create
libreyolo/models/swin/, which already exists and holds a shared backbone that
Grounding DINO imports.
Check four things, not one:
- The family directory (
libreyolo/models/<family>/). - The
FAMILYid andFILENAME_PREFIXyou intend to claim, against every existing family. - The architecture as a component. A model can already be in the tree as a
shared backbone or neck without being a family of its own
(
git grep -l "<ArchName>" upstream/dev -- libreyolo). docs/nomenclature.mdandweights/LICENSE_NOTICE.txt, which sometimes record a family before or after the code moves.
If it already exists, stop and write a short note instead of a PRD: what is shipped, what is genuinely missing, and the one or two residual tasks worth doing. Save that note the same way (section 6). A PRD for a shipped model wastes an entire implementation cycle.
2. License gate
Run libreyolo-license-audit for the verdict. Do not improvise licensing
judgement here. What this skill adds is what the PRD must record.
Two different bars, and collapsing them is the most common error:
- Code vendored into core must be MIT, Apache-2.0 or BSD. No GPL, AGPL, LGPL, non-commercial or unknown-license code, ever, including rewrites.
- Weights only need to be redistributable. Non-commercial weights are shippable when tagged accordingly. Weights that forbid redistribution are not a blocker either: link upstream instead of rehosting (the YOLO-NAS precedent).
Consequences the PRD must state explicitly:
- A permissive reimplementation rescues a tainted original. Both original FCOS repos open with a non-commercial clause, so neither may be read or ported, but torchvision ships a BSD-3 FCOS and that is a clean path. Name the source to use and the source to stay out of.
- Never launder. Rewriting non-permissive code to disguise its origin is prohibited regardless of how the result looks.
- Primary sources only, with evidence URLs in the PRD. The GitHub license
API (
https://api.github.com/repos/<org>/<repo>/license), the rawLICENSEfile, and the HF model card YAML. Never a recollection, never a badge. - Say "implied" when it is implied. Most weights carry no per-artifact license and inherit it from the releasing repository. torchvision publishes none at all and explicitly disclaims that pretrained models "may have their own licenses or terms and conditions derived from the dataset used for training". Write that distinction on the model card rather than upgrading an inference into a stated grant.
- Check per-variant, not per-model. Licenses differ across sizes and generations. MiDaS is MIT, but its v2 and v2.1 checkpoints were fine-tuned from CC-BY-NC pretraining, so only some variants are clean.
- Watch the backbone init. A "trained by us" checkpoint often starts from a third-party backbone whose license still applies.
- Beware the popular decoy. The most-starred implementation is often the unusable one. Name it in the PRD so nobody finds it later and assumes it is fine.
3. Port source and scaffold
Pick the source that combines permissive code with loadable weights, preferring the one whose module names match the checkpoints so conversion stays a metadata-wrap. State the runner-up and why it lost, because the implementer will otherwise rediscover it.
For the scaffold, read the per-family ledger in libreyolo-port-model
(its section 4) and name a concrete directory to clone. Then check the
identifiers you are claiming do not collide, and list the families whose
can_load could steal your checkpoints, so the PRD can require bidirectional
rejection tests.
4. Scope and evidence
Say which tasks are in scope and declare SUPPORTED_TASKS explicitly. Then pick
an implementation and evidence target from libreyolo-port-model section 2.
Prefer a trainable port whenever practical. Do not default to inference-only
merely to reduce the first implementation's scope. If a safe, reproducible
fine-tuning path exists, include training support in the handoff's initial
definition of done. Inference-only remains legitimate when a concrete technical,
licensing, data, or compute constraint prevents useful user fine-tuning.
Whether the PRD requires a trainer follows three implementation facts:
- Task shape. The task is closed-set and label-supervised: the user's dataset is images plus plain labels the existing pipeline already carries (boxes, masks, keypoints, class ids). Prompt-driven, text-conditioned, zero-shot and multimodal models (SAM, VLMs, CLIP, open-vocab detectors, foundation backbones) do not use the ordinary supervised trainer surface: their "training" is web-scale pretraining, not user fine-tuning.
- Upstream recipe. Upstream ships a permissively licensed fine-tuning implementation (loss, assignment, recipe) that converges on a small dataset on a single GPU. A pretraining pipeline needing multi-node or web-scale data does not count (Depth Anything V2's teacher-student distillation is the precedent: supervised task, no user-facing recipe, inference-only).
- Integration feasibility. LibreYOLO's data pipeline can represent the required labels, the necessary training operators can be implemented from compatible sources, and a normal user can fine-tune on practical hardware. Needing web-scale data, multi-node pretraining, unavailable custom kernels, or unsupported annotations fails this gate. Historic or museum status alone does not.
All three pass: the PRD requires a trainer, includes training in the definition of done, and states the completed checks and remaining validation work. If delivery must be staged, make training a named second milestone in the same handoff rather than an unspecified optional follow-up. Splitting it into a separate handoff requires an explicit maintainer decision. Any gate fails: inference-only, and the PRD names the failed gate, the supporting evidence, and what would need to change for training to become feasible. Genuinely unsure: write "implementation scope: maintainer call" in the PRD and ask, instead of guessing.
The one-line intuition: ship a trainer when a real user could run
model.train(data="their_small_dataset.yaml") on one GPU and expect a better
model; ship inference-only when "training" really means "pretraining nobody
can reproduce".
Also name the coverage group the family enters (MODEL_GROUPS in
libreyolo/models/registry.py; semantics in docs/nomenclature.md, "Model
groups"). Group membership mirrors the implemented surface and selects
cross-family tests; it never grants or removes a capability. The implementer
copies the selected group into the registry at commit 1, and
tests/unit/test_model_registry.py blocks merge until they do.
5. The PRD document
Use these sections, in this order. It is the shape that has survived adversarial review, and a consistent shape is what lets an implementing agent trust it.
# Handoff: add <MODEL> as a LibreYOLO <task> family
**For:** an implementing agent starting fresh.
**Process authority:** skills/libreyolo-port-model/SKILL.md.
## 0. Mandatory gates (the non-negotiables, see below)
## 1. The model (architecture, variants/sizes, historic significance)
## 2. License (verdict + evidence URLs + rehost-or-link decision)
## 3. Why we did not add it before
## 4. Why we are adding it now
## 5. Head start already in-tree (closest scaffold, and its traps)
## 6. Scope and evidence
## 7. Implementation pointers (family id, can_load, converter, export contract)
## 8. Definition of done (checklist mirroring section 0)
Section 0 always carries these gates:
- Upstream parity:
max_abs_diff == 0.0in eval mode against the recommended source, for every shipped size, before any postprocess, export or trainer code exists. If the port vendors the same implementation it compares against, that check is tautological: say so and give a meaningful alternative (published metric reproduction, or parity against the reference the weights came from). - Export parity, separately: the exported graph must match our PyTorch output on the same image. "The export runs" is not the bar (see section 7).
- Weights: rehost per
libreyolo-upload-hf-modelwhen redistributable, or link upstream when not. Verify auto-download on a cleared cache. - Tests: the right registration for the task (see section 7).
- UI smoke check: load one converted checkpoint through the UI and confirm predict renders.
- Training decision: when all three training gates in section 4 pass, include a trainer and its convergence evidence in the definition of done. Otherwise name the failed gate and evidence instead of silently scoping training out.
Close with the branch rule: branch off dev and land the work through
merge-to-dev. An agent may open the PR but never approves or merges it. The PR
body must contain a filled ## Code provenance section, which
provenance-check.yml enforces by matching a ^#{1,6}\s*code provenance$
heading and failing when it is missing or empty.
Style: no em dashes or en dashes, no personal names, no machine-specific paths. State only what you verified, and tell the implementer to verify at port time where you could not.
6. Save locally
A model-port handoff is a local working artifact, not a public artifact.
- Resolve the current user's Documents directory. On Windows, prefer the
operating system's
MyDocumentslocation. On other platforms, use the configured documents directory or fall back to~/Documents. - Create a
handoffsdirectory inside it when needed. - Save the document as
<Documents>/handoffs/HANDOFF_<family>_<task>.md, using lowercase family and task slugs with underscores only where separators are needed. - Keep the handoff outside every repository worktree so it cannot be staged or committed accidentally.
- Never upload the handoff as a Gist, publish it through another remote service, or edit a GitHub issue or pull request to register it.
- Before saving, scan for leakage: no credentials, real names, usernames, email addresses, or machine-specific paths inside the document. Use repository-relative paths in the handoff body.
- Return the absolute local file path to the user. Do not return or create a public URL.
7. Facts PRD authors get wrong
Verified against dev. Each of these has already shipped in a PRD and had to be
corrected.
from_pretraineddoes not exist.LibreYOLOis a factory function (libreyolo/models/__init__.py) that takes a path. The auto-download check isLibreYOLO("Libre<Family><size>.pt")on a cleared cache with no staged copy underweights/. Do not write afrom_pretrainedcall into a PRD; the bare canonical filename is the download trigger.- A non-YOLO-grid export needs two backend edits, not one.
_is_nms_free_family()is a module-level function inlibreyolo/backends/base.py(not aBaseBackendmethod) and only decides whether NMS is re-applied after parsing. The parse itself is family dispatched in_parse_outputs, whose finalelsefalls through to_parse_yolo9and reads the graph as a(4+nc, N)YOLO tensor. A DETR-shaped graph parsed that way returns garbage while appearing to export fine. Route to_parse_dfinelike the shipped DETR families. Never cite line numbers for either: they move between branches. MODEL_CATALOGis detect-only. It drivestest_val_coco128.pyand its mAP50-95 gate, so a classify, depth or semantic-segmentation row fails by construction. Point those families at a per-family unit suite instead, and check what the closest merged family actually registers before writing the gate.- Historic model, modern artifact. For older models the cleanly licensed implementation is often not the historic one: torchvision's AlexNet is the "one weird trick" variant, its VGG weights were trained from scratch rather than converted from the original release, and its FCN has no skip fusion. Ship the modern rebuild if you like, but require the PRD to say so plainly on the model card rather than exhibiting a replica under a historic name.
- Weight hosting rots. Checkpoints living only on Google Drive or a personal academic host need rehosting early in the port, not at the end.