porting-8-ship
Stage 8 (final) verifies prior artifacts, drafts release docs, renders the HF README, and pushes docs/README to the private HF repo. Public release is out of scope.
Preconditions
- All earlier stages 1–7 complete.
reports/porting/<family>/<variant>/intake.jsoncomplete.reports/porting/<family>/forward-map.mdcomplete.tests/golden/<family>/<variant>.manifest.jsoncomplete.tests/tolerances/<family>.jsonreviewed and committed (no_provisionalflags).reports/convert/<variant>-<REFDTYPE>.json(SHA of the reference GGUF).reports/wer/<variant>-<PRESET>.<dataset>.score.jsonfor every shipped preset.reports/perf/<machine>/*_<variant>_<backend>.jsonfor both publication rigs (Apple M4 Max and AMD Ryzen 7 PRO 4750U), each run on that rig. See the Reference machine matrix inporting-6-bench.
Workflow
Ship progress:
- [ ] Step 1: Pre-flight checklist (artifacts present)
- [ ] Step 2: Fill the family doc
- [ ] Step 3: Author the user-facing model card
- [ ] Step 4: Write the HF card YAML spec
- [ ] Step 5: Render the HF README
- [ ] Step 6: Pre-upload review
- [ ] Step 7: Sign-off review
Step 1: Pre-flight checklist (execute)
Confirm every artifact exists. If any row is missing, halt and send the user to the stage that owns the missing artifact — Stage 8 does not fabricate inputs.
| Artifact | Expected path | Owning stage |
|---|---|---|
| Intake | reports/porting/<family>/<variant>/intake.json |
Stage 1 |
| Manifest | tests/golden/<family>/<variant>.manifest.json |
Stage 2 |
| Tolerances | tests/tolerances/<family>.json |
Stage 4 |
| Forward map | reports/porting/<family>/forward-map.md |
Stage 4 |
| Converter report | reports/convert/<variant>-<REFDTYPE>.json |
Stage 3 |
| Quants | models/<variant>/<variant>-*.gguf |
Stage 5 |
| Bench reports, rig 1 | ### Apple M4 Max section in docs/models/<variant>.md |
Stage 6 |
| Bench reports, rig 2 | ### AMD Ryzen 7 PRO 4750U section in docs/models/<variant>.md |
Stage 6 |
| WER score JSONs | reports/wer/<variant>-*.<dataset>.score.json |
Stage 7 |
| WER summary | reports/wer/<variant>.<dataset>.summary.md |
Stage 7 |
# Mechanical checklist runner
for path in \
reports/porting/<family>/<variant>/intake.json \
tests/golden/<family>/<variant>.manifest.json \
tests/tolerances/<family>.json \
reports/porting/<family>/forward-map.md \
reports/convert/<variant>-<REFDTYPE>.json \
reports/wer/<variant>.<dataset>.summary.md
do
[ -f "$path" ] && echo "OK $path" || echo "MISSING $path"
done
ls models/<variant>/<variant>-*.gguf >/dev/null 2>&1 \
&& echo "OK quants" || echo "MISSING quants"
# Bench: reports/ is gitignored and each rig keeps its own JSON locally, so
# the checkable artifact is the rendered rig section in the model card.
# BOTH rigs are required. A base apple-m4 (or any other dev box) does not
# substitute for either.
for rig in "Apple M4 Max" "AMD Ryzen 7 PRO 4750U"; do
grep -q "^### $rig" docs/models/<variant>.md \
&& echo "OK bench-rig: $rig" || echo "MISSING bench-rig: $rig"
done
grep -q "^ m4-max:" scripts/hf_cards/<variant>.yaml \
&& echo "OK perf yaml m4-max" || echo "MISSING perf yaml m4-max"
grep -q "^ ryzen-4750u:" scripts/hf_cards/<variant>.yaml \
&& echo "OK perf yaml ryzen-4750u" || echo "MISSING perf yaml ryzen-4750u"
ls reports/wer/<variant>-*.<dataset>.score.json >/dev/null 2>&1 \
&& echo "OK wer-scores" || echo "MISSING wer-scores"
Any MISSING halts Stage 8.
A MISSING bench-rig is the one row that is easy to wave through, because
a model card with one rig table looks finished. It is not: publication
scope is two rigs (porting-6-bench, Reference machine matrix). Send the
user back to Stage 6 on the missing rig. The only way past it is the user
explicitly signing off on shipping with one rig, in which case the card
must name the rig the numbers were measured on.
Step 2: Family doc (execute + ask-point)
Open docs/porting/families/<family>.md. If still the _template.md
shape, fill it section by section by pulling facts from the artifacts:
- Identity — from
intake.json:family,hf_repo,hf_revision,variants[], license from the HF model card. - References — from
intake.reference_framework,intake.reference_rationale, andmanifest.reference.entrypoint. - Environment — from
scripts/envs/<family>/pyproject.toml. - Artifacts — paths to manifest, tolerances, forward-map, converter report, validation-report bundle, bench reports, WER reports.
- Commands — concrete
uv runinvocations for reference dumps, conversion, validation, bench, WER. Match the existing shape ofdocs/porting/families/parakeet.mdorcohere.md. - Notes — anything the port surfaced that didn't fit elsewhere:
tensor-name mapping decisions, reference-framework quirks, known drift
sources paraphrased from the tolerances
_commentblock.
For a new family, draft the Known Limitations section from intake capabilities (streaming flag, translation flag, language coverage, timestamp granularity) plus any sharp edges the port surfaced. Do not invent limitations the port didn't discover; do not omit limitations the capabilities flags imply. Present the draft for human review in Step 6.
State the batch and streaming posture from the Capability Validation rows:
- Batch: confirm the family ships an explicit
run_batch()parallel fast path (PASS — batchingMUST PASS, not optional) and that it is WER-neutral (byte-identical to single-stream). Serial fallback is reportable only asACCEPTED GAP — serial (benchmarked no faster), or as an explicit user-signedBLOCKER; it is never a silent default. - Streaming: if
capabilities.streamingis true the row is PASS — say so and name the chunk/lookahead contract; it is never reported as an accepted gap for a natively-streaming model. If the model does not stream, omit the row.
Step 3: User-facing model card (execute)
Author docs/models/<variant>.md. The repo ships a Jinja template at
docs/_templates/model-card.md.j2 and existing rendered cards (e.g.
docs/models/parakeet-tdt-0.6b-v2.md) are the shape reference.
Two acceptable approaches:
- Copy from the closest existing model card and edit by hand. Pull
facts directly from artifacts — quants from
models/<variant>/, WER and the measured reference baseline fromreports/wer/<variant>-*.score.json, bench fromreports/perf/<machine>/on both rigs (one###section each,Apple M4 Maxwith metal/cpu andAMD Ryzen 7 PRO 4750Uwith vulkan/cpu, each footnoted with its OS and the transcribe.cpp sha), and the acceptance dataset fromintake.upstream_benchmarks[0]. Ask fortarget_hf_reposince it cannot be inferred. - Render from the existing template if the template already covers
everything the variant needs and the variant has no rendered card
yet. Build the context dict in a short ad-hoc
uv run python -cand write the output. Do not extend the template with new context fields just for one family — handcraft those sections in the rendered markdown instead.
Subsequent regenerations must respect human edits.
Step 4: HF card YAML spec (execute)
Write scripts/hf_cards/<variant>.yaml, mirroring
scripts/hf_cards/parakeet-tdt-0.6b-v2.yaml:
hf_repo: <intake.hf_repo>
target_repo: <user-provided e.g. handy-computer/<variant>-gguf>
transcribe_docs_url: https://github.com/handy-computer/transcribe.cpp/blob/main/docs/models/<variant>.md
upstream_commit: <intake.hf_revision short sha>
pin_date: <today>
validation:
reference: <intake.reference_framework>
commit: <current repo HEAD short sha>
date: <today>
license: <from upstream model card>
license_display: <human-facing form>
pipeline_tag: automatic-speech-recognition
languages: [<from intake.capabilities.languages>]
tags:
- gguf
- transcribe.cpp
- asr
- speech-to-text
- <family>
- <architecture-style>
Step 5: Render the HF README (execute)
uv run scripts/hf_cards/generate.py scripts/hf_cards/<variant>.yaml
Writes models/<variant>/README.md by default.
Step 6: Pre-upload review (ask-point)
Drafts from Steps 2, 3, and 5 are now on disk. Present three paths for human review:
docs/porting/families/<family>.mddocs/models/<variant>.mdmodels/<variant>/README.md
Flag likely over-promising sections (one_liner, capabilities_prose,
Known Limitations) and wait for explicit sign-off before Step 7.
Step 7: Sign-off
Report:
- All four output paths (family doc, model card, HF YAML, HF README).
- Target private HF repo.
- Pre-flight checklist outcome from Step 1.
- Push the rendered docs/README to the private repo:
hf upload <target_repo> models/<variant> . --repo-type model - Remind the user to commit the docs/families/models/hf_cards changes.
- If this port adds a new family (or new variants under an existing
family), remind the user to update the supported-models table in the
root
README.mdso the family/variants are listed.
Do not commit. Keep the repo private; flipping it public is a future action, not part of this stage.
Postconditions
- Pre-flight checklist (Step 1) was green before any drafting.
docs/porting/families/<family>.mdfilled and reviewed.docs/models/<variant>.mdauthored with a populated download / WER / bench table, the bench carrying both rig sections (Apple M4 Max, AMD Ryzen 7 PRO 4750U) unless the user signed off on fewer.scripts/hf_cards/<variant>.yamlcommitted-ready.models/<variant>/README.mdrendered.- Docs/README pushed to the private HF repo; public flip deferred.
Pointers (read, not execute)
docs/porting/families/_template.md— family doc shapedocs/models/parakeet-tdt-0.6b-v2.md— model card shape referencescripts/hf_cards/parakeet-tdt-0.6b-v2.yaml— HF card YAML referencescripts/hf_cards/template.md.j2— Jinja template that generate.py rendersscripts/hf_cards/generate.py— renderer (execute only via Step 5)