Problem
check-upstream-drift.sh (SessionStart hook) currently fires the "N commits behind upstream/main" banner on every forked ops repo whenever any commit lands on me2resh/apexyard:main. That includes:
- README typo fixes
- CI tweaks
- Docs-only PRs
- Dependency bumps on the landing page
None of those are things a fork owner needs to sync. The banner becomes background noise, and over time trains fork owners to ignore it — which defeats the whole point of having a drift-detection system in the first place.
The ops-fork model assumes upstream is curated (releases are tagged), so the signal we actually want is: "a new tagged release exists that my fork doesn't have."
Proposal
Switch the default drift-detection signal from main..upstream/main commit count to tag diff:
-
check-upstream-drift.sh — after git fetch upstream --tags, compare the latest upstream tag against the fork's last-merged tag. If the upstream has a newer tag (semver-ordered), show a banner naming the release: ApexYard: v1.1.0 available. Run /update to sync. Silent otherwise, even if main..upstream/main has commits.
-
/update skill — preview both signals:
- "N commits behind upstream/main" (informational, dim)
- "New release available: vX.Y.Z (previously vA.B.C)" (actionable, bold)
Only nag on the tag; the main-commit count is supporting detail.
-
Config override in apexyard.projects.yaml (optional) — upstream_sync_mode: tag | main. Defaults to tag. Someone who wants the bleeding-edge behaviour can opt into main.
-
Fallback: if the upstream has never been tagged (or the fork has never merged an upstream tag), fall back to main..upstream/main so new forks still get a useful banner before the first release sync.
Acceptance criteria
Out of scope
- Automating
/update invocation (still manual).
- Release-notes surfacing inside the banner (the banner just names the tag; the user reads notes via
/update).
- Patch-version vs minor-version gating (any new tag fires — let semver convention + humans decide urgency).
Context
- Current hook:
.claude/hooks/check-upstream-drift.sh uses git rev-list --count main..upstream/main.
- Current skill:
.claude/skills/update/SKILL.md uses the same.
- Why the noise matters: upstream apexyard is a framework with hundreds of future fork-users. Every spurious banner compounds across the whole user base. Fix once, fix for everyone.
Problem
check-upstream-drift.sh(SessionStart hook) currently fires the "N commits behind upstream/main" banner on every forked ops repo whenever any commit lands onme2resh/apexyard:main. That includes:None of those are things a fork owner needs to sync. The banner becomes background noise, and over time trains fork owners to ignore it — which defeats the whole point of having a drift-detection system in the first place.
The ops-fork model assumes upstream is curated (releases are tagged), so the signal we actually want is: "a new tagged release exists that my fork doesn't have."
Proposal
Switch the default drift-detection signal from
main..upstream/maincommit count to tag diff:check-upstream-drift.sh— aftergit fetch upstream --tags, compare the latest upstream tag against the fork's last-merged tag. If the upstream has a newer tag (semver-ordered), show a banner naming the release:ApexYard: v1.1.0 available. Run /update to sync.Silent otherwise, even ifmain..upstream/mainhas commits./updateskill — preview both signals:Only nag on the tag; the main-commit count is supporting detail.
Config override in
apexyard.projects.yaml(optional) —upstream_sync_mode: tag | main. Defaults totag. Someone who wants the bleeding-edge behaviour can opt intomain.Fallback: if the upstream has never been tagged (or the fork has never merged an upstream tag), fall back to
main..upstream/mainso new forks still get a useful banner before the first release sync.Acceptance criteria
v1.1.0on upstream, a fresh fork's SessionStart DOES show a banner namingv1.1.0./updateclearly distinguishes "behind main" from "new release available".main..upstream/maindrift but no new tag stop seeing the banner after they merge once.Out of scope
/updateinvocation (still manual)./update).Context
.claude/hooks/check-upstream-drift.shusesgit rev-list --count main..upstream/main..claude/skills/update/SKILL.mduses the same.