# Porting 8 Ship

> porting-8-ship

- Skill: `handy-computer/porting-8-ship` (Agent Skill)
- Install (CLI): `npx skillmds@latest add handy-computer/porting-8-ship`
- Raw SKILL.md: https://api.skillmd.com/api/skills/handy-computer/porting-8-ship/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: handy-computer (https://skillmd.com/u/handy-computer)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/handy-computer/porting-8-ship

---


# 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.json` complete.
- `reports/porting/<family>/forward-map.md` complete.
- `tests/golden/<family>/<variant>.manifest.json` complete.
- `tests/tolerances/<family>.json` reviewed and committed (no
  `_provisional` flags).
- `reports/convert/<variant>-<REFDTYPE>.json` (SHA of the reference GGUF).
- `reports/wer/<variant>-<PRESET>.<dataset>.score.json` for every shipped
  preset.
- `reports/perf/<machine>/*_<variant>_<backend>.json` for **both**
  publication rigs (Apple M4 Max and AMD Ryzen 7 PRO 4750U), each run
  on that rig. See the Reference machine matrix in `porting-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 |

```bash
# 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`, and `manifest.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 run` invocations for reference dumps,
  conversion, validation, bench, WER. Match the existing shape of
  `docs/porting/families/parakeet.md` or `cohere.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 `_comment` block.

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 — batching `MUST PASS`, not optional) and that it is
  WER-neutral (byte-identical to single-stream). Serial fallback is
  reportable only as `ACCEPTED GAP — serial (benchmarked no faster)`, or as an
  explicit user-signed `BLOCKER`; it is never a silent default.
- Streaming: if `capabilities.streaming` is 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:

1. **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 from
   `reports/wer/<variant>-*.score.json`, bench from
   `reports/perf/<machine>/` on **both** rigs (one `###` section each,
   `Apple M4 Max` with metal/cpu and `AMD Ryzen 7 PRO 4750U` with
   vulkan/cpu, each footnoted with its OS and the transcribe.cpp sha),
   and the acceptance dataset from
   `intake.upstream_benchmarks[0]`. Ask for `target_hf_repo` since it
   cannot be inferred.
2. **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 -c`
   and 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`:

```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)

```bash
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>.md`
- `docs/models/<variant>.md`
- `models/<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:
  ```bash
  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.md` so 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>.md` filled and reviewed.
- `docs/models/<variant>.md` authored 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>.yaml` committed-ready.
- `models/<variant>/README.md` rendered.
- Docs/README pushed to the private HF repo; public flip deferred.

## Pointers (read, not execute)

- `docs/porting/families/_template.md` — family doc shape
- `docs/models/parakeet-tdt-0.6b-v2.md` — model card shape reference
- `scripts/hf_cards/parakeet-tdt-0.6b-v2.yaml` — HF card YAML reference
- `scripts/hf_cards/template.md.j2` — Jinja template that generate.py
  renders
- `scripts/hf_cards/generate.py` — renderer (execute only via Step 5)

