Agent skill

Rollout Phase B

by tetherto in tetherto/qvac

Phase B of a qvac-fabric rollout — tag the merged fabric commit, publish to registry, land the consumer side (vcpkg bumps + package versions + changelogs for all 7 consumers) as one PR, post one…

Apache-2.0Auto-check passedDevelopment

Install Rollout Phase B

skills CLI
$ npx skills add tetherto/qvac --skill rollout-phase-b -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install tetherto/qvac rollout-phase-b --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/tetherto/qvac.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packages/ocr-ggml/.agent/skills/rollout-phase-b .claude/skills/rollout-phase-b && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
rollout-phase-b
GitHub stars
681
Token cost
~9.1k tokens
SKILL.md length
4,576 words
Files
1
Skills in repo
50
Repo updated
First seen
Licence
Apache-2.0

At a glance

Phase B of a qvac-fabric rollout — tag the merged fabric commit, publish to registry, land the consumer side (vcpkg bumps + package versions + changelogs for all 7 consumers) as one PR, post one…

  • Tasks that involve Changelog and release notes
  • SKILL.md covers THE GOLDEN RULE, Step 0 — Preflight, then ask, --bump-only (resume mode) and B1 — Tag + Registry, plus 2 more sections
  • Calls git, gh and jq; reaches github.com; needs GH_TOKEN

What it does

Rollout Phase B is an agent skill from tetherto/qvac. Phase B of a qvac-fabric rollout — tag the merged fabric commit, publish to registry, land the consumer side (vcpkg bumps + package versions + changelogs for all 7 consumers) as one PR, post one Slack message. Pass --bump-only to resume a part-done rollout and do just the version + changelog work. Pass --on-top-of-pr to put the whole consumer side onto an open PR — revert the overlay commit Phase A placed there AND land the bumps on that same PR, instead of opening a separate bundled PR.

Its SKILL.md is about 9.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Changelog and release notes. It works with Slack. The repository describes itself as: Open-source local AI SDK - run AI on-device with no cloud, no API keys. Supports GGUF, RAG, image, music, and video generation, speech-to-text, P2P inference, and more… The licence is Apache-2.0.

When your agent uses it

  • Tasks that involve Changelog and release notes

Example prompts

  • “/rollout-phase-b”

What it can do on your machine

Read from SKILL.md and the folder at commit c3a6030. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • git
    • gh
    • jq
    • npm
    • curl

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • GH_TOKEN

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Rollout Phase B loads about 9.1k tokens when it runs. Until then it costs about 127 tokens; SKILL.md has 4,576 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~127
When it runs · the whole SKILL.md, loaded when a task matches
~9.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from tetherto/qvac at commit c3a6030, republished under its Apache-2.0 licence (© tetherto). 4,576 words, ~9,097 tokens.

Download SKILL.mdSave it as .claude/skills/rollout-phase-b/SKILL.md (or your agent's skills folder).
name
rollout-phase-b
description
Phase B of a qvac-fabric rollout — tag the merged fabric commit, publish to registry, land the consumer side (vcpkg bumps + package versions + changelogs for all 7 consumers) as one PR, post one Slack message. Pass --bump-only to resume a part-done rollout and do just the version + changelog work. Pass --on-top-of-pr to put the whole consumer side onto an open PR — revert the overlay commit Phase A placed there AND land the bumps on that same PR, instead of opening a separate bundled PR.
argument-hint
<fabric-version> <merge-commit-sha> [--bump-only] [--on-top-of-pr <pr-url>]

Rollout Phase B — Tag + Registry + Bundled Consumer PR

Prerequisites: Fabric PR merged. Phase A all green. v<VERSION> tag does NOT exist yet.

The 7 consumers: embed-llamacpp, fabric, llm-llamacpp, model-fit, ocr-ggml, translation-nmtcpp, vla-ggml.

classification-ggml is not a fabric consumer — it dropped the qvac-fabric vcpkg dependency and now consumes the published npm package @qvac/fabric. It needs neither overlay validation nor a version>= bump during a rollout. Do not re-add it.

THE GOLDEN RULE

Never bump default-registry.baseline in vcpkg-configuration.json. Anywhere. Ever.


Step 0 — Preflight, then ask

Do this before anything else, in every mode. Nothing in B1 or B2 runs until the user approves.

Where the fabric details come from
CaseBehaviour
Given on the invocationUse them verbatim, for the whole run.
Not givenDerive from context (ladder below), recording the source of each value.
NeitherName what is missing and stop.

What was supplied is what gets used. Do not substitute the registry's latest published version, the consumers' version>= floors, or the newest fabric tag for a value the user gave you, and do not "correct" a supplied value to one of them. Remote resolution below annotates the values; it never replaces them.

The version is passed bare — 10069.0.0, not v10069.0.0. git tag v<VERSION> and the registry portfile's REF v${VERSION} both add the v. A v-prefixed value is malformed: report the expected form and ask, rather than silently stripping it.

Derivation ladder — only for values that were NOT given

Take the first that yields a value, and remember which one it was:

  1. This session — a /rollout-phase-a run, or a version stated explicitly.
  2. The overlay port's own version — vcpkg-overlays/ports/qvac-fabric/vcpkg.json "version", on the Phase A validation branch or (in --on-top-of-pr mode) on the target PR's head branch. Phase A Step 2 sets this to the exact target. Best source when either branch is to hand.
  3. --bump-only only: the 7 consumers' vcpkg.json "version>=", which must all agree. In this mode the floors are the target — that is the mode's precondition.
  4. <merge-commit-sha>: the HEAD of the release branch temp-<N> (see below), or the fabric PR's merge commit.

Never derive a NEW version from the registry's latest entry, the newest v* tag, or the current version>= floors. All three hold the previous version, so a value taken from them re-tags an already-tagged commit and republishes a live one. --bump-only is the single exception, because there the previous version is the target.

The release line is temp-<N>, not master

Fabric releases are cut from branches named temp-<upstream-llama.cpp-build>, and the version is <build>.<major>.<minor>. master tracks upstream and is not the release line — comparing a release commit against it reports diverged and tells you nothing.

VersionRelease branchTag sits at
10069.0.0temp-10069branch HEAD (63bfbdea0)
9341.1.6temp-9341branch HEAD (55325c0c8)

So <merge-commit-sha> should be on temp-<N> for the <N> leading the version you are publishing. A commit that is not is the strongest available signal that the version and the commit disagree.

Resolve against the remote — read-only

tetherto/qvac-fabric-llm.cpp is public; no token needed.

FactCommand
does v<VERSION> already existgit ls-remote --tags https://github.com/tetherto/qvac-fabric-llm.cpp "v<VERSION>"
release-branch HEADgit ls-remote https://github.com/tetherto/qvac-fabric-llm.cpp "refs/heads/temp-<N>"
commit subject + dategh api repos/tetherto/qvac-fabric-llm.cpp/commits/<sha> --jq '{sha:.sha,msg:.commit.message,date:.commit.committer.date}'
is the commit on temp-<N>gh api repos/tetherto/qvac-fabric-llm.cpp/compare/temp-<N>...<sha> --jq .status → identical or behind means yes

Expected tag state — flag it, never resolve it yourself:

  • full run → v<VERSION> must NOT exist; if it does, proceeding re-tags a published version
  • --bump-only → v<VERSION> must exist; if it does not, the registry PR probably has not merged
Where the overlay is, and the safety net

--on-top-of-pr <pr-url> says Phase A put its overlay commit on an open PR rather than a dedicated validation branch. Step 5b reverts it — and B2's bumps land on that same PR, not on a new one. See the mode table at the head of B2; the flag governs the whole consumer side, not just the revert.

If the flag is absent, still look. Run the completeness sweep in Step 5b against the working repo before proceeding. If it finds overlay artefacts, stop — name exactly what was found and which branch or PR carries it, and say --on-top-of-pr is required:

/rollout-phase-b: refusing to bump over a live overlay.

  ! vcpkg-overlays/ports/qvac-fabric/       present on <branch>
  ! "overlay-ports" key in 7 packages/*/vcpkg-configuration.json

An overlay makes vcpkg resolve qvac-fabric from the local portfile instead of the
registry, silently. Bumping the floors now ships a version that was never validated
against the published port.

Re-run with --on-top-of-pr <pr-url>, or remove the overlay first.

This is the same invariant --bump-only preflight check 6 enforces; the flag is what tells the skill where to go and fix it rather than only complain.

Present, then ask

Print every value with its provenance, then ask. The label is what lets the user catch a bad derivation — it is the reason deriving is safe at all, so never omit it:

Phase B — confirm before proceeding:

  fabric version   10069.0.0    (as given)
  tag to create    v10069.0.0   ⚠ already exists — proceeding re-tags a published version
  release branch   temp-10069
  merge commit     63bfbdea0    (derived: temp-10069 HEAD)
                   "Merge pull request #204 …"   2026-08-06
  mode             full (B1 + B2) — bumps land on a new branch off origin/main

The mode row must name where the bumps will land, so a wrong target is caught before anything is pushed. In --on-top-of-pr mode it reads:

  mode             full (B1 + B2) — bumps land on PR #3725, no separate PR

--bump-only shows the version, that v<VERSION> exists, and that the registry has published it — no commit row.

--on-top-of-pr adds two rows naming what Step 5b will revert, resolved before the prompt so the user can catch a wrong PR or a missing overlay commit while it is still cheap:

  overlay on       PR #3352  head QVAC-21981/abot-world @ a2d3265d
  reverting        5a950ade2  "… overlay-validate the 7 fabric consumers against …"

Then AskUserQuestion with exactly:

Proceed · Correct a value (say which) · Abort

When a ⚠ is present, Proceed's description must name what is being accepted. The run does not start until Proceed is chosen — silence is not consent, and approval is required even when every value resolves cleanly.

If nothing yields a version

Name the missing value and stop. Never guess a version, never default it, never fall back to the newest tag:

/rollout-phase-b: no fabric version supplied, and none could be derived.
usage: /rollout-phase-b <fabric-version> <merge-commit-sha> [--bump-only]
   eg: /rollout-phase-b 10069.0.0 63bfbdea0
Nothing was changed. Re-run with the version you intend to publish.

--bump-only (resume mode)

For the common resumed state: the fabric tag is pushed, the registry PR merged, and the vcpkg.json floors already bumped — all that is left is the mechanical version + changelog work.

Skips B1 entirely, and skips Step 7 sub-steps 1–3. Performs only Step 7 sub-step 4 (package.json) and sub-step 5 (CHANGELOG.md), for all 7 consumers. Everything the mode skips, it first verifies was actually done.

Combining it with --on-top-of-pr is legitimate — the overlay outlives a part-done rollout as easily as a whole one. In that combination Step 5b still runs, before the bumps, and preflight check 6 is what it satisfies. The bumps land on the target PR here too, and checks 2 and 7 below need the merge-base treatment (Step 5b's $BASE) rather than origin/main, since the target branch is not cut fresh from main.

Preflight — verify, then stop or proceed

Step 0 runs first. These checks compare against the version the user confirmed there; if Step 0 never reached approval, none of this runs. --bump-only does not make the version optional — the mode skips B1's work, not its input, though it does widen how the version may be derived (Step 0's ladder item 3).

Run all checks and report every failure in one list. Do not stop at the first — a part-done rollout usually has more than one gap, and drip-feeding them wastes a round trip each.

#CheckHow
1Working repo is the real code repo on the right remotegit -C <repo> remote -v → tetherto/qvac
2On a branch off origin/main — not main, not release-* (in --on-top-of-pr mode: on the target PR's head branch)git -C <repo> rev-parse --abbrev-ref HEAD
3Fabric tag v<VERSION> existsgit -C <fabric-repo> ls-remote --tags <remote> "v<VERSION>"
4qvac-fabric <VERSION> is published to the registrysee command below — non-null result means published
5All 7 vcpkg.json "version>=" already equal <VERSION>read each packages/<consumer>/vcpkg.json
6Overlay fully removedthe completeness sweep in Step 5b, repo-wide — not just the 7
7No default-registry.baseline driftgit -C <repo> diff $BASE -- "packages/*/vcpkg-configuration.json" → empty ($BASE = origin/main, or the merge base in --on-top-of-pr mode)
8Per consumer: origin/main package.json version vs npmnpm view @qvac/<pkg> dist-tags.latest

Check 4 — request the raw blob so no base64 decoding is needed:

bash
gh api repos/tetherto/qvac-registry-vcpkg/contents/versions/q-/qvac-fabric.json \
  -H "Accept: application/vnd.github.raw" --jq '[.versions[].version] | index("<VERSION>")'

A number means published; null means the registry PR has not merged — stop.

Check 5 — parse the JSON; do not grep a fixed line offset from "name": "qvac-fabric". The dependency object's shape varies between consumers — three of the seven carry extra keys, so a grep -A1 reports the floor as missing when it is present and correct:

ConsumerExtra keys on the qvac-fabric dependency
ocr-ggmldefault-features, features
translation-nmtcppdefault-features, features
vla-ggmlfeatures

Read the version>= field out of the parsed object.

Check 6 matters more than it looks. A leftover overlay makes vcpkg resolve qvac-fabric from the overlay instead of the registry — silently. Nothing errors; you would ship a bump that was never validated against the published port.

Run Step 5b's sweep for it rather than checking only the 7 consumers — an overlay added by hand outside the roster resolves just as silently. On failure, name the branch or PR still carrying it and point at --on-top-of-pr; a bare "check 6 failed" leaves the user to find it themselves.

Check 8 has four outcomes, not pass/fail:

OutcomeMeaningDo
npm == origin/mainnormal — the bump is genuinely pendingproceed
npm behind origin/maina bump already landed and is unreleasedstop and ask before adding another (/bump-version Step 1's rule)
npm ahead, major differsthe package's line was renumbered — see belowproceed on the origin/main number
npm ahead, same linewrong checkout or wrong branchstop

Two cases that look like failures and are not:

  • A package reading 0.0.0 on npm with no release tag has never been published — 0.0.0 is npm's name placeholder, not a real release, so it presents as the behind case. Do not paper over it; ask whether the version already on origin/main should publish as-is before bumping past it. (model-fit was the standing instance and has since published — re-derive rather than assume; npm view @qvac/<pkg> dist-tags.latest plus git ls-remote --tags origin "<prefix>-v*".)
  • @qvac/translation-nmtcpp reads 10.0.0 on npm against 0.8.0 on origin/main: the renumbered case, not a bad checkout. Its main line was restarted at 0.x (there is a live release-0.7 dist-tag at 0.7.0), so npm's latest will stay numerically ahead indefinitely. origin/main is the authority for the bump. Confirm the branch is right, then proceed from 0.8.0.

Step 7 sub-step 3 (Phase A C++ fixes) cannot be verified mechanically. Do not claim a check you did not perform. Instead print the non-manifest diff and have the user confirm:

bash
git -C <repo> diff --stat $BASE -- "packages/*/addon" "packages/*/src"

($BASE = origin/main, or the merge base in --on-top-of-pr mode — on a target PR branch origin/main folds in the author's own C++ and makes this unreadable.)

On success — apply the bumps

/bump-version is the single source of truth for bump level and changelog shape. Note that it is disable-model-invocation: true, so it cannot be invoked programmatically — follow its written Steps 3–5 procedure here. (Alternative, if you prefer the skill itself: run /bump-version <pkg> per package by hand, using /bump-version translation-nmtcpp major for the one post-1.0 package.)

  • Bump level comes from the table in Step 7 sub-step 4 below: 0.x → minor, >=1.0 → major. /bump-version never auto-selects major, so any package on >=1.0 must be given the level explicitly. As of 2026-08-13 no consumer is — all seven are 0.x, translation-nmtcpp included. Do not pass major for it out of habit; see Step 7 sub-step 4.
  • Changelog entries use the fabric-only wording in Step 7 sub-step 5, with the bracketed ## [<version>] - <date> heading.
  • model-fit's CHANGELOG has a ## [Unreleased] block — insert the dated entry below it, per /bump-version Step 5. Inserting above makes the release extractor slice the body off.
Stop point

Apply the 14 edits (7 × package.json + 7 × CHANGELOG.md), then stop and confirm before committing. Print:

  1. a summary table — pkg · old → new · level;
  2. git -C <repo> diff --stat $BASE — or, in --on-top-of-pr mode, git diff --cached --stat, since the target branch carries the author's work and can never reduce to the 14 files.

Assert the diff touches only package.json and CHANGELOG.md across the 7 packages — anything else means something got swept in. Then ask the user to confirm before continuing into Step 9 (commit / push) and Step 10 (PR — or, in --on-top-of-pr mode, updating the target PR instead of creating one). Never commit unattended in this mode.


B1 — Tag + Registry

Step 1: Tag the merged fabric commit
bash
git -C <fabric-repo-path> tag v<VERSION> <merge-commit-sha>
git -C <fabric-repo-path> push upstream v<VERSION>

(upstream = whichever remote points at tetherto/qvac-fabric-llm.cpp — it may be named origin in a direct clone; check git remote -v.) Verify: git -C <fabric-repo-path> show v<VERSION> --stat

Step 2: Compute SHA512 of the tag tarball
bash
curl -fsSL https://github.com/tetherto/qvac-fabric-llm.cpp/archive/v<VERSION>.tar.gz -o /tmp/fabric-tag.tgz
vcpkg hash /tmp/fabric-tag.tgz
Step 3: Update registry portfile (tetherto/qvac-registry-vcpkg)
  • ports/qvac-fabric/portfile.cmake: update SHA512 to the tag tarball's hash. That is the only edit. REF is already REF v${VERSION}, parameterized off the port's vcpkg.json — do not replace it with a literal REF v<VERSION>; de-parameterizing the portfile is a review rejection.
  • ports/qvac-fabric/vcpkg.json: "version": "<VERSION>" — bumping this is what moves the ref.
  • Update versions DB:
    bash
    vcpkg --x-builtin-registry-versions-dir=versions x-add-version qvac-fabric
Then clean up after x-add-version — the diff must stay minimal

x-add-version writes "port-version": 0 into the new entry, and may retro-add it to entries that are already published. Both are noise. Delete the field from the new entry, and revert any change to an existing entry.

The rule: omit port-version when it is 0 — absent already means 0. Include it only when non-zero, which a <VERSION>#1 port rebuild genuinely needs.

Do not argue from file-local style. The file's entries are inconsistent (some carry the field, some do not), so "most of them have it" is not evidence that it is required — and normalizing a published entry to match is a drive-by edit to something live.

Prove it is unnecessary with the idempotency re-run, after the edit:

bash
vcpkg --x-builtin-registry-versions-dir=versions x-add-version qvac-fabric --verbose
# expect: "version <VERSION> is already in …versions/q-/qvac-fabric.json"
#         "No files were updated for qvac-fabric"

That output means vcpkg considers the entry complete and correct. If it instead rewrites the file or demands --overwrite-version, the entry really is wrong — fix it rather than forcing it.

vcpkg x-add-version --verify does not exist (error: unexpected switch: --verify). The idempotency re-run above is the check; do not go looking for a --verify flag.

Assert this diff shape before pushing. Anything beyond it is noise:

ports/qvac-fabric/portfile.cmake | 2 +-      (SHA512 only)
ports/qvac-fabric/vcpkg.json     | 2 +-      (version only)
versions/baseline.json           | 2 +-      (baseline string only)
versions/q-/qvac-fabric.json     | 4 ++++    (pure insertion)

A +4/-2-shaped hunk in qvac-fabric.json means an existing entry was modified — revert that part. Leave baseline.json's pre-existing per-entry port-version keys alone: that file's convention is its own, and the rollout changes only the baseline string.

After any amend, re-assert the recorded git-tree — it must equal the git-tree in the new entry:

bash
git rev-parse HEAD:ports/qvac-fabric
Step 4: Verify the portfile locally — mandatory, isolated, and reported

This step is not optional and not satisfiable by a green exit code. Read the trap first.

The false pass — a clean exit here usually means nothing was built

vcpkg's install plan is satisfied by any installed version of the port. A shared install root holding an older qvac-fabric short-circuits the whole thing:

The following packages are already installed:
    qvac-fabric[core,llama]:x64-linux@9840.0.1
Total install time: 156 us
All requested installations completed successfully in: 156 us

That is exit 0 having verified nothing — no download, no hash check, no compile, and the new version never mentioned. A fast, clean, cheerful exit is the failure signature here, not success. (The same reason --overwrite-version does not re-install locally: only a clean root rebuilds.)

Always isolate the roots

An existing local vcpkg checkout is fine — it is the install root that must be fresh, not the tool. Isolation is the part that matters; pick the host triplet for whatever machine you are on.

bash
GH_TOKEN=$(gh auth token) vcpkg install qvac-fabric \
  --overlay-ports=<path-to-qvac-registry-vcpkg-clone>/ports \
  --triplet <host-triplet> \
  --x-install-root=<tmp>/vcpkg-installed \
  --x-buildtrees-root=<tmp>/vcpkg-bt \
  --x-packages-root=<tmp>/vcpkg-pkg
Positive assertions — all three must appear, each naming <VERSION>
Must appear in the logProves
Downloading …/archive/v<VERSION>.tar.gz + Successfully downloadedthe new tag was actually fetched
Building qvac-fabric[…]@<VERSION>the plan resolved the new version, not a cached one
All requested installations completed successfullythe port builds

A SHA512 mismatch is a hard failure before the build, so reaching "Building" is itself the hash gate passing. Sanity-check the elapsed time too: a real build is minutes. Microseconds or seconds means you hit the false pass above.

Re-verification after an amend

If git rev-parse HEAD:ports/qvac-fabric is unchanged, the build result still holds — a versions/-only amend (e.g. removing port-version) needs no re-run. If the ports/ tree changed, re-run this step.

Step 5: Open registry PR

Push branch to tetherto/qvac-registry-vcpkg, create PR.

Report the verification when you present the PR. State that it was built locally and how: version built, triplet, features, that the install root was isolated, and that the three Step 4 assertions held. A registry PR handed over without that line is incomplete — the reviewer cannot tell a real verification from the false pass above.

If Step 4 was skipped or could not run, say so explicitly. Silence reads as "verified".

Show full SKILL.md (2,015 more words)Show less
Step 5b: Strip the overlay from the target PR — --on-top-of-pr only

Skip this step entirely in the default mode; Step 8 covers the validation-branch case.

Why here. The revert lands after B1 has published <VERSION>, and it is immediately followed by B2's bump on the same branch, in the same push (5b.5 below). The overlay comes off and the floors go up as one transition, so the PR never sits in a state where it resolves neither the overlay nor the new version.

Before the target PR is closed or merged. If it has been closed or already merged by the time you get here, --on-top-of-pr has nothing to attach to: fall back to the default separate-PR path (Steps 6–10 as written), and say plainly in the report that the fallback was used and why. The tag is already pushed at this point — do not stall the rollout waiting on a decision.

  1. Check out the target PR at its current head. gh pr checkout <n> --repo tetherto/qvac, then pull. Commits may well have landed since Phase A — do not assume the head you saw then.

  2. Locate the overlay commit, first hit wins:

    bash
    git log --grep="^Rollout-Overlay:" --format=%H origin/main..HEAD
    git log --diff-filter=A --format=%H -- vcpkg-overlays/ports/qvac-fabric

    …then the SHA supplied by the user. The first is the trailer Phase A Step 5 writes; the second catches overlays predating it. More than one hit means the overlay was re-pinned mid-validation — revert them newest first, or the older revert conflicts with the newer state.

  3. Revert.

    bash
    git revert --no-commit <overlay-sha>

    If it conflicts — later commits touched those files — fall back to explicit removal (git rm -r vcpkg-overlays/ports/qvac-fabric, and Edit the overlay-ports key out of each of the 7 vcpkg-configuration.json) and say the fallback was used. A conflicting revert usually means something else edited the overlay, which is worth a human looking at.

  4. The completeness sweep. Every check runs; report all failures together. It is deliberately repo-wide rather than scoped to the 7 consumers:

    Diff against the merge base, not origin/main's tip — set it once and reuse:

    bash
    BASE=$(git merge-base origin/main HEAD)
    CheckPasses when
    the revert is the exact inverse of the overlaygit diff <overlay-sha>^ HEAD -- vcpkg-overlays "packages/*/vcpkg-configuration.json" → empty
    port subtree gonegit diff $BASE -- vcpkg-overlays → empty
    no key left anywheregit grep -l "overlay-ports" -- "**/vcpkg-configuration.json" → no output
    no baseline driftgit diff $BASE -- "packages/*/vcpkg-configuration.json" → empty
    nothing left behindgit status --porcelain → clean

    The first check is the strongest — it asserts the tree is byte-identical to before the overlay went on, across exactly the paths Phase A touched. The third is what catches an overlay someone added by hand outside the 7.

    vcpkg-overlays/ itself stays: triplets/ and toolchains/ are permanent repo infrastructure and only the ports/qvac-fabric subtree is rollout scaffolding. The second check passing is what proves you removed the one and not the other.

    Why the merge base and not origin/main. A long-lived target PR forked a while ago, so git diff origin/main reports everything main has landed since — which reads as drift the rollout caused. Real instance: packages/diffusion-cpp/vcpkg-configuration.json appeared to have lost a "reference": "main" key, which was actually PR #3551 landing on main post-fork.

    Reading a hit: a package outside the 7 consumers, or a key other than baseline, is almost always a staleness artifact. Re-measure against $BASE before reporting it as drift — and never "fix" it, since it is not yours.

  5. Do NOT push the revert on its own. Go straight into B2 (Step 7) on this same branch and commit the bumps as a separate commit, then push once — two commits, one push, one CI trigger.

    Pushing the revert alone leaves the PR resolving the previously published fabric until a later push, which is both a wasted CI run and a green that means nothing about <VERSION>.

    The push itself needs confirmation: this is someone else's PR. Show the revert diffstat, the bump diffstat, and the sweep results, get confirmation, then push to the PR's head branch.

  6. Say what the PR builds against now. With the overlay gone and the floors at <VERSION>, the target PR resolves <VERSION> from the registry as soon as the registry PR merges. Until it does, the PR's CI is red on an unresolvable version>= — expected, and the same condition Step 10's CI note describes. Retrigger after the registry PR merges.

    Say this out loud rather than letting someone read the red as a real failure, or the eventual green as evidence gathered before the registry landed.


B2 — The consumer bumps (ONE PR for all 7 consumers)

Rule: One PR carries everything: the 7 vcpkg.json bumps, any C++ changes from Phase A, the 7 package.json bumps, and the 7 CHANGELOG.md entries. Do not split per package.

Which PR that is depends on the mode:

ModeWhere the consumer bumps land
defaulta new branch off origin/main → a new bundled PR (Steps 6, 9, 10 as written)
--on-top-of-prthe target PR's head branch, as a second commit alongside the Step 5b revert. No new branch, no new PR.

--on-top-of-pr exists precisely so the consumer code needing the new fabric and the fabric bump meet on the same PR. Opening a separate bump PR recreates the problem the flag was added to solve — the target PR's CI keeps building against the old published fabric, and the two only meet after the whole rollout lands (see /rollout-phase-a's "Two modes"). If you find yourself running git checkout -b in this mode, stop.

Step 6: Branch from origin/main — NOT from the Phase A branch
bash
git fetch origin
git checkout -b TICKET/bump-fabric-<VERSION> origin/main

--on-top-of-pr: skip this step. You are already on the target PR's head branch from Step 5b. Do not branch from origin/main and do not create TICKET/bump-fabric-<VERSION>.

Step 7: For each of the 7 consumers, on this one branch:
  1. Check the current package.json version on origin/main — other PRs may have landed since Phase A; do NOT assume the version from Phase A.

    --on-top-of-pr: origin/main is the wrong base to read, and the failure is silent until merge time. Read the version off the target branch, and compare every one of the 7 against origin/main before bumping anything:

    bash
    for p in embed-llamacpp fabric llm-llamacpp model-fit ocr-ggml translation-nmtcpp vla-ggml; do
      printf "%-20s branch=%-8s main=%s\n" "$p" \
        "$(git show HEAD:packages/$p/package.json | jq -r .version)" \
        "$(git show origin/main:packages/$p/package.json | jq -r .version)"
    done
    OutcomeMeaningDo
    equalbranch is current for that packagebump normally
    branch behind mainthe branch predates a releaseupdate the branch with origin/main first, then re-read
    branch ahead of mainthe PR already bumped that packagedo not double-bump — fold the fabric changelog line into the entry the PR already added

    Bumping across a stale base ships a wrong number and a conflict. Real instance: a target branch read llm-llamacpp 0.42.0 while origin/main was 0.43.0, so a naive bump produced 0.42.0 → 0.44.0 with no 0.43.0 CHANGELOG entry, and a modify/modify conflict against main's own 0.42.0 → 0.43.0 the moment the PR merged.

    Updating someone else's branch changes their PR's history — confirm the method (merge vs rebase) with the user before doing it.

  2. Bump vcpkg.json "version>=" to <VERSION>.

  3. Apply C++ changes from Phase A (llm-llamacpp only if applicable): Use the Edit tool for specific lines. Do NOT run:

    bash
    git checkout <phase-a-branch> -- file.cpp  # WRONG — takes whole file, causes regressions
  4. Bump package.json — a new fabric version means a new package version, API change or not. Which component moves depends on where the package already is:

    Current versionBumpExample
    0.x.y (pre-1.0)minor0.31.0 → 0.32.0
    x.y.z where x >= 1major9.0.0 → 10.0.0

    Read the current version off origin/main (sub-step 1 above) before deciding — do not assume.

    As of 2026-08-13 all seven consumers are 0.x, so every one takes the minor path — embed-llamacpp 0.32.0, fabric 0.4.0, llm-llamacpp 0.42.0, model-fit 0.1.0, ocr-ggml 0.16.0, translation-nmtcpp 0.8.0, vla-ggml 0.19.0. Treat that roster as illustration and the rule as the authority — these versions move every release.

    translation-nmtcpp no longer takes the major path. Older revisions of this skill said it did, on the strength of it sitting at 9.0.0 (it went 8.3.1 → 9.0.0 in #3567 for a dependency-floor alignment, then 9.0.0 → 10.0.0). Its main line has since been restarted at 0.x — npm still carries latest = 10.0.0 and a release-0.7 line at 0.7.0, while origin/main reads 0.8.0. Applying the old advice bumps 0.8.0 → 1.0.0, an unintended major release. Read the version off origin/main and apply the table; do not special-case this package.

    model-fit at 0.1.0 bumps to 0.2.0 — pre-1.0, so it takes the minor path even though it looks like a large jump.

  5. Add a CHANGELOG.md entry. Heading MUST be ## [<version>] - <date> (bracketed — release workflow requires this format).

    For llm-llamacpp (if API changes):

    markdown
    ## [<version>] - <date>
    
    ### Added
    - <describe new API>
    - `qvac-fabric` dependency bumped `<old>` → `<new>`.

    For the other 6 (fabric-only):

    markdown
    ## [<version>] - <date>
    
    ### Changed
    - `qvac-fabric` dependency bumped `<old>` → `<new>` (<feature>; no API change for this package).
Step 8: Check overlay absent

Run Step 5b's completeness sweep on this branch too — it is the same invariant, and keeping one definition stops the two drifting apart. In the default mode this branch is cut fresh from origin/main, so the sweep should pass untouched and $BASE is just origin/main.

In --on-top-of-pr mode Step 5b already cleaned the target PR — re-run the sweep after the bump commit to confirm it stayed clean, keeping the $BASE merge-base form.

vcpkg-overlays/ports/qvac-fabric/ and the "overlay-ports" blocks must NOT exist on this branch. If the Phase A branch was merged to main, remove them here: git rm -r vcpkg-overlays/ports/qvac-fabric and drop the "overlay-ports" block from each consumer's vcpkg-configuration.json. Leave the rest of vcpkg-overlays/ (triplets/, toolchains/) alone — only the ports/qvac-fabric subtree is rollout scaffolding. No other edits to vcpkg-configuration.json — no baseline bump.

Step 9: Confirm all files, commit, push to origin
bash
git push origin TICKET/bump-fabric-<VERSION>

origin = tetherto/qvac (cloned directly, not a fork).

Assert the change is exactly the 21 files (7 × vcpkg.json + package.json + CHANGELOG.md), plus any Phase A C++ from Step 7 sub-step 3.

--on-top-of-pr: assert on the commit, not on origin/main. The branch carries the PR author's own work, so git diff --stat origin/main can never reduce to the 21 files and the assertion is meaningless there. Use the bump commit itself:

bash
git show --stat HEAD          # after committing
git diff --cached --stat      # before committing

Then push to the target PR's head branch — one push carrying the 5b revert and this commit together, after the confirmation in 5b.5.

Step 10: Create PR

Title: TICKET feat[api]: bump qvac-fabric to <VERSION> across consumers Body: link fabric PR + registry PR. Squash-merge when green — the squash commit lands on qvac main, so make its message clear and self-explanatory (what bumped, to which <VERSION>, across which addons).

CI note: the PR will fail until the registry PR merges (version>= can't resolve yet). Expected — retrigger CI after the registry merges, before requesting review.

Gotcha: never rename a branch that has an open PR via the API — GitHub orphans/closes the PR (head ref disappears, can't reopen). Create the PR with the final branch name.

--on-top-of-pr — do NOT create a PR

The target PR is the consumer PR. Creating another one is the mistake this mode exists to prevent. Instead:

  • The push already happened in 5b.5. Nothing to open.
  • Update the target PR's body (or add a comment) with the rollout facts: the fabric PR and tag, the registry PR link, the 7 version bumps, and the CI-red-until-the-registry-merges note.
  • Tell the user the blast radius changed, because it is easy to miss: the target PR now also carries 7 package releases, so squash-merging it publishes them. Its title/tags may need to reflect an API-affecting change, and if the PR belongs to someone else, the author needs to know their feature PR is now also a release PR.
  • Escape hatch, as in 5b: if the target PR turned out closed or already merged, fall back to the default path above and say the fallback was used.

Post Slack message (once both PRs open)

Please review the <feature name>.
Registry PR: https://github.com/tetherto/qvac-registry-vcpkg/pull/<N>
Consumer bump (all 7 packages — vcpkg + package versions + changelogs, single PR):
• https://github.com/tetherto/qvac/pull/<N>

In --on-top-of-pr mode there is no separate bump PR — the consumer line points at the target PR, and should say the bump rides it so nobody goes looking for a second one:

Please review the <feature name>.
Registry PR: https://github.com/tetherto/qvac-registry-vcpkg/pull/<N>
Consumer bump rides the feature PR (all 7 packages — vcpkg + package versions + changelogs):
• https://github.com/tetherto/qvac/pull/<N>  ← also publishes the 7 packages when squash-merged

If you have no Slack access, print the message (with the links) to the console so the user can post it.

© tetherto, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in packages/ocr-ggml/.agent/skills/rollout-phase-b of tetherto/qvac.

Open the folder on GitHubat commit c3a6030

Compare with similar skills

Rollout Phase B next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Rollout Phase B compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Rollout Phase B this skilltetherto/qvac681—~9.1kAutomated safety check: PassApache-2.0
Release DigestKiln-AI/Kiln5.2k—~2.7kAutomated safety check: PassCustom licence
Pre Releaserusq/slackdump2.8k—~841Automated safety check: PassAGPL-3.0
Releaseshaharia-lab/slackcli229—~1.9kAutomated safety check: PassMIT
Releaseforcedotcom/salesforcedx-vscode1k—~1.7kAutomated safety check: PassBSD-3-Clause
Announce Prereleaseforcedotcom/salesforcedx-vscode1k—~960Automated safety check: PassBSD-3-Clause

Similar skills

  • Release Digest

    Kiln-AI/Kiln

    Post a "what's changed since the last release" recap to the release Slack channel for final QA.

    5.2k GitHub stars~2.7k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Pre Release

    rusq/slackdump

    Prepare this repository for a release. An agent skill from rusq/slackdump.

    2.8k GitHub stars~841 tokensUpdated 5 days ago
    DevelopmentAuto-check passed
  • Release

    shaharia-lab/slackcli

    Cut a new SlackCLI release end to end — survey commits since the last tag, recommend a SemVer bump, open the release issue, prepare the version bump and CHANGELOG promotion on a branch, open the…

    229 GitHub stars~1.9k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Release

    forcedotcom/salesforcedx-vscode

    Run the VS Code extension release workflow end-to-end. An agent skill from forcedotcom/salesforcedx-vscode.

    1k GitHub stars~1.7k tokensUpdated today
    DevelopmentAuto-check passed
  • Announce Prerelease

    forcedotcom/salesforcedx-vscode

    Compose and send Slack announcement for pre-release builds. An agent skill from forcedotcom/salesforcedx-vscode.

    1k GitHub stars~960 tokensUpdated today
    DevelopmentAuto-check passed
  • Changelog Orchestrator

    jeremylongshore/tons-of-skills-marketplace

    Draft changelog PRs by collecting GitHub/Slack/Git changes, formatting with templates, running quality gates, and preparing a branch/PR.

    2.8k GitHub stars~694 tokensUpdated today
    DevelopmentAuto-check passed

More from tetherto/qvac

All 50 skills in this repo
  • Creates a Solutions page in the QVAC documentation website from a real use case, generalizing the case into reusable guidance and registering the page in the site navigation.

    681 GitHub stars~2.8k tokensUpdated yesterday
    Auto-check passed
  • Qv Docs Update

    tetherto/qvac

    Updates the docs website after a change to the SDK or CLI. An agent skill from tetherto/qvac.

    681 GitHub stars~11k tokensUpdated yesterday
    Auto-check passed
  • Qv Agent Stack Sync

    tetherto/qvac

    Plan and prepare the QVAC agent-stack release cascade across @qvac/inference, @qvac/sdk, @qvac/cli, @qvac/ai-sdk-provider, @qvac/opencode-plugin, and @qvac/openclaw-plugin.

    681 GitHub stars~2k tokensUpdated yesterday
    Auto-check passed
  • Run the deterministic code-quality audit, turn related findings into contextual remediation groups, prepare approval-gated Asana proposals, reconcile recurring runs, or configure twice-monthly…

    681 GitHub stars~1.6k tokensUpdated yesterday
    Auto-check passed
  • Review C++ changes for string parameter and call-site efficiency conventions (std::stringview, std::string&&, const std::string&, const char, and TransparentStringMap lookup).

    681 GitHub stars~702 tokensUpdated yesterday
    Auto-check passed
  • Qv Addon Changelog

    tetherto/qvac

    Generate changelog entries for a target add-on package. An agent skill from tetherto/qvac.

    681 GitHub stars~1.7k tokensUpdated yesterday
    Auto-check passed

Works with

Categories

Questions about Rollout Phase B

What does Rollout Phase B do?

Phase B of a qvac-fabric rollout — tag the merged fabric commit, publish to registry, land the consumer side (vcpkg bumps + package versions + changelogs for all 7 consumers) as one PR, post one…. Rollout Phase B is an agent skill from tetherto/qvac. Phase B of a qvac-fabric rollout — tag the merged fabric commit, publish to registry, land the consumer side (vcpkg bumps + package versions + changelogs for all 7 consumers) as one PR, post one Slack message.

When should I use Rollout Phase B?

Rollout Phase B fits situations like: tasks that involve Changelog and release notes.

How do I install Rollout Phase B in Claude Code?

Run `npx skills add tetherto/qvac --skill rollout-phase-b -a claude-code`. Or copy the skill folder (packages/ocr-ggml/.agent/skills/rollout-phase-b in tetherto/qvac) into .claude/skills/rollout-phase-b in your project. Claude Code loads it when a task matches its description.

How do I install Rollout Phase B in Codex?

Run `npx skills add tetherto/qvac --skill rollout-phase-b -a codex`. Or copy the skill folder (packages/ocr-ggml/.agent/skills/rollout-phase-b in tetherto/qvac) into .agents/skills/rollout-phase-b in your project. Codex loads it when a task matches its description.

Can I use Rollout Phase B in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add tetherto/qvac --skill rollout-phase-b -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/rollout-phase-b, .gemini/skills/rollout-phase-b, .github/skills/rollout-phase-b and .opencode/skills/rollout-phase-b in your project.

What does Rollout Phase B need to run?

Going by SKILL.md and its folder, Rollout Phase B needs the command-line tools its instructions call (git, gh, jq, npm and curl) and credentials named GH_TOKEN.

Does Rollout Phase B access the network?

SKILL.md names 1 domain. In commands or code: github.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is Rollout Phase B safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Rollout Phase B use?

Rollout Phase B is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Rollout Phase B use?

About 9.1k tokens (SKILL.md is roughly 36k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Rollout Phase B?

Skills that share tags, products or a category with Rollout Phase B: Release Digest (Kiln-AI/Kiln, 5.2k stars), Pre Release (rusq/slackdump, 2.8k stars), Release (shaharia-lab/slackcli, 229 stars) and Release (forcedotcom/salesforcedx-vscode, 1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Rollout Phase B?

tetherto (a GitHub organization) maintains it in tetherto/qvac, which has 681 GitHub stars. The repository holds 50 skills in this directory. The repository was last updated on October 7, 2026.

Source: tetherto/qvac on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.