name: sync-upstream description: Reconcile fork master with Netflix/vmaf master. Detects the fork's port-only topology (no shared merge-base) and emits a coverage report; falls back to merge-based sync when the histories are actually connected.
<!-- markdownlint-disable MD029 MD046 -->/sync-upstream
Invocation
/sync-upstream [--open-pr]
Background — why pre-flight matters
The fork has been maintained with a port-only strategy: each upstream
commit is cherry-picked, rebranded (feat: port upstream X, subject preserved),
and squash-merged. That produces commit SHAs on fork master that do not
descend from the upstream-master SHAs they originated from. As a result,
git merge-base master upstream/master returns empty — the histories are
formally unrelated.
Running a bare git merge upstream/master --no-ff in that state requires
--allow-unrelated-histories and produces thousands of spurious conflicts
(every fork-local file collides with its upstream counterpart by path,
regardless of content). The skill must detect this topology before attempting
a merge.
Steps
-
Pre-flight: topology detection.
git fetch upstream mb=$(git merge-base master upstream/master 2>/dev/null) || true- If
mbis empty → port-only topology. Go to step 2a (coverage check). - If
mbis non-empty → merge-based topology. Go to step 2b (classic merge).
- If
2a. Port-only coverage check. For each upstream commit reachable from
upstream/master since the last fork-side port anchor:
bash # Derive a reasonable upper bound: the last 50 upstream commits. # Expand as needed; subjects are the match key. git log upstream/master --pretty=format:'%H%x09%s' -50 > /tmp/sync-upstream-candidates.tsv
**Pass 1 — subject-line match (cheap, catches PRs that cite the upstream
SHA in their subject):**
```bash
while IFS=$'\t' read -r sha subj; do
if git log master --pretty=format:'%s' \
| grep -Fxq "$subj"; then
echo "PORTED $sha $subj"
else
echo "UNPORTED $sha $subj"
fi
done < /tmp/sync-upstream-candidates.tsv
```
**Pass 2 — content-hash similarity for `UNPORTED` rows (catches silent
ports where the same change was made by a fork dev without citing
upstream).** PR #295's 2026-05-02 sync report missed 4 of 6 candidates
that turned out to be already on the fork — Pass 2 catches that class:
```bash
# For each UNPORTED upstream commit, extract added/changed identifiers
# and check if they exist in fork master's HEAD. If yes, it's silently
# ported (the change shipped without an SHA citation in the commit subject).
for sha in $(awk '/^UNPORTED/ {print $2}' /tmp/sync-upstream-pass1.tsv); do
# Extract added/changed identifiers from the upstream commit
# (function names, variable names, string literals it INTRODUCES).
idents=$(git show "$sha" --no-color --pretty=format:'' \
| grep -E '^\+[^+]' \
| grep -oE '[a-zA-Z_][a-zA-Z0-9_]{4,}' \
| sort -u)
# Skip if no useful identifiers (e.g. doc-only or formatting commit).
[ -z "$idents" ] && continue
# Probe fork master for at least 80% of the identifiers.
n_total=$(echo "$idents" | wc -l)
n_present=$(echo "$idents" | xargs -I{} sh -c \
'git grep -lq "{}" -- master 2>/dev/null && echo present' | wc -l)
ratio=$((n_present * 100 / n_total))
if [ "$ratio" -ge 80 ]; then
echo "PORTED-SILENTLY $sha ratio=$ratio% n_total=$n_total"
else
echo "UNPORTED $sha ratio=$ratio%"
fi
done
```
The 80% threshold is empirical: at `ratio=80%+`, the upstream commit's
semantic content is overwhelmingly already in fork master; at `<50%` the
commit is genuinely missing. The 50–80% band is fuzzy and requires
eyeballing the commit's substance vs the fork's tree.
**Categorise the final output:**
- `PORTED` (Pass 1 hit) — fork commit cites the SHA in its subject.
- `PORTED-SILENTLY` (Pass 2 hit) — semantic content present, no SHA
citation. Surface in the report so the maintainer can decide whether
to backfill a citation. NOT a `/port-upstream-commit` candidate.
- `UNPORTED` (neither pass hit) — genuinely missing. Recommend
`/port-upstream-commit <sha>`.
- If every listed commit is `PORTED` or `PORTED-SILENTLY` → exit with
`sync-upstream: no action — fork at parity with upstream/master @ <tip-sha>`.
- If any are `UNPORTED` → list them and recommend
`/port-upstream-commit <sha>` for each. Do NOT attempt a merge. This is
the expected outcome in port-only mode.
2b. Merge-based sync. Only reached when mb is non-empty:
bash git switch -c sync/upstream-$(date +%Y%m%d) master git merge upstream/master --no-ff
Conflict policy (matches D16):
- Fork wins for: .github/, README.md, CLAUDE.md, AGENTS.md,
.claude/, Dockerfile*, core/meson_options.txt, anything under
core/src/cuda/, core/src/sycl/, core/src/feature/{cuda,sycl}/,
core/src/feature/x86/, core/src/feature/arm64/.
- Upstream wins for: feature metric code not touched by the fork —
identify by checking git log --follow origin/master -- <path> for
any fork commits.
- Manual resolution required: core/include/libvmaf/libvmaf.h,
core/src/libvmaf.c, core/meson.build,
core/tools/cli_parse.cpp, core/tools/vmaf.cpp.
For manual conflicts, STOP and surface them with file:line context. Do
NOT resolve.
-
On clean merge (step 2b only):
/build-vmaf --backend=cpu,meson test -C build,/cross-backend-diffon the normal Netflix pair. -
If
--open-pr(step 2b only):gh pr createwith titlechore(upstream): sync to upstream/master @ <sha>and body including upstream commit count, conflict summary, and test results.- In port-only mode (step 2a),
--open-pris a no-op when coverage is complete; when gaps exist, the recommendation is one PR per/port-upstream-commit <sha>invocation, not a single sync PR.
- In port-only mode (step 2a),
Guardrails
- Refuses to run if working tree is dirty.
- Refuses to open a PR if the Netflix CPU golden tests fail after merge.
- Never
git push --force. - Pre-flight short-circuit is mandatory — the classic merge step MUST NOT
be reached when no merge-base exists, even under operator override, because
the
--allow-unrelated-historiesfallback has been known to corrupt hand-curated port history (see ADR-0028 and the post-mortem thread in docs/rebase-notes.md).
Docker Compose Architect
DevOps
Designs optimized Docker Compose configurations.
Incident Postmortem Writer
DevOps
Writes structured and blameless incident postmortem reports.
Runbook Creator
DevOps
Creates clear operational runbooks for common DevOps procedures.