Slash command
/upgrade-impact
Report only the breaking changes in an upgrade that actually occur in this repository, with the compiler's own deprecation output as the evidence.
The prompt
What it actually sends
A skill is a prompt template, not code. This is the whole of it — expanded fresh on every call, with $ARGUMENTS and $1..$9 filled in from what you type.
Report what upgrading one dependency, SDK or toolchain would break in the repository
at $CWD. What to upgrade, and to what — <name> <target version>, or a toolchain such
as AGP 8.5, Xcode 16, targetSdk 35, React Native 0.75: $ARGUMENTS
The deliverable is the intersection of two sets: what changed upstream, and what this repository actually touches. An upstream changelog restated in your own words is not the deliverable — the caller can read it, it lists the changes that matter to everyone, and the reason they asked you is that they want the ones that matter here.
1. Pin both ends before anything else
The current version is what the lockfile says, not what the manifest permits. A manifest range answers "what would resolve", the lockfile answers "what is in this build", and only the second one can break.
grep -n -A2 "PODS:" Podfile.lock
grep -n "<pkg>" Package.resolved package-lock.json yarn.lock pubspec.lock
grep -rn "<coordinate>" gradle/libs.versions.toml */gradle.lockfilePrint both versions with the path:line each came from. When the target version is not named in $ARGUMENTS, ask for it and stop; "the latest" is a moving target and the answer would be about a version nobody chose.
2. Say at the top whether you read the migration guide
The first line of the report states one of:
Migration guide: read — <path on disk, or URL fetched this session>, orMigration guide: NOT READ — <exactly what was tried>.
A guide on disk beats a page: node_modules/<pkg>/CHANGELOG.md, the -sources.jar in
the Gradle cache, ~/.pub-cache/hosted/pub.dev/<pkg>-<version>/CHANGELOG.md, a pod's
own CHANGELOG.md under Pods/. When the guide was not read, every entry in the report
that would have come from it is absent rather than reconstructed, and the report says how
much that costs — "N breaking changes upstream, unknown; this report is compiler
evidence only" is an honest report, and a plausible list is not.
3. Prefer the compiler to any list
The compiler has read every line of this repository against the SDK on this machine. No changelog has. When a build can be run, its warnings outrank every other source in this report, and the real command and its real output are quoted:
./gradlew :app:compileReleaseKotlin --warning-mode all
./gradlew :app:lintRelease
xcodebuild -scheme <Scheme> -destination 'generic/platform=iOS' build 2>&1 | grep -E "deprecated|will be removed"
npx tsc --noEmit
flutter analyzeRun these against the current versions to collect deprecations the upstream project
has already announced — that is the cheapest and most reliable signal of what the next
version removes. When the target version can be resolved in a scratch checkout, run them
again against it and diff. When no build can be run at all, write
Compiler evidence: NOT RUN — <why>; do not describe warnings you did not see.
4. Tie every breaking change to an occurrence here
For each candidate change — from the guide, from the deprecation output, from the release notes — search this repository for a real use:
grep -rn "<removed symbol>" --include=*.kt --include=*.java --include=*.swift \
--include=*.m --include=*.ts --include=*.tsx --include=*.dart .- Occurrences found → the change is in the report, with every path:line listed.
- No occurrence → the change is dropped, and the drop count is reported. A reader has to be able to tell a filtered list from a short one, and the printed pattern is what lets them check that the filter was not the bug.
5. Then the parts a grep cannot see
State these as their own section, so nobody mistakes the report's silence for safety:
- Reflection, DI graphs, string-keyed registries,
Class.forName,NSClassFromString, Kotlin/Swift KSP or macro output, and anything generated at build time. - Transitive dependents: run the resolver, not your memory —
./gradlew :app:dependencies,npm ls <pkg>,flutter pub deps,swift package show-dependencies. Each dependent isCOMPATIBLEonly when a file read this session says so — a version range in its manifest, a constraint in its podspec. Otherwise it isUNKNOWN. There is no third state and no "should be fine". - Floors the upgrade moves: a library raising
minSdk, a pod raising the deployment target, an AGP release requiring a newer JDK, an Xcode release dropping an OS. These break the build without appearing in any call site, and they are read from the dependency's own manifest, not recalled. - Runtime-only behaviour changes: a
targetSdkbump changes OS behaviour for code that compiles unchanged, so its evidence is the platform's behaviour-changes page for that level, quoted, with the call sites the change applies to.
The refusals
- It never lists a breaking change it cannot tie to an occurrence in this repository. A change with no call site here is dropped and counted, not reported "for awareness".
- It never marks a dependent compatible from memory. With no file that states the
constraint, the status is
UNKNOWN — <the command that would settle it>. - It never reports a compiler result it did not run. The substitute is
Compiler evidence: NOT RUN — <why>, and the section that would have used it is empty. - It never silently reconstructs an unread migration guide. The top line says
NOT READand the report stands on compiler evidence alone. - It never proposes the migration edit. It names the call sites and, where a source
it actually read states the replacement, quotes that statement with its origin. Where
no source states it, the line is
migration: not stated by any source read — author must supply.
Output
UPGRADE: <name> <current> → <target>
current pinned at: <lockfile path:line>
target named by: <caller | file>
Migration guide: read (<source>) | NOT READ (<what was tried>)
Compiler evidence: <command> → <n deprecation warnings> | NOT RUN (<why>)
BREAKS HERE (<n>)
1. <change> — <n occurrences>
<path:line>
<path:line>
migration: <quoted from <source>> | not stated by any source read — author must supply
2. …
FLOORS MOVED (<n>)
<minSdk | deployment target | JDK | Xcode> <old> → <new> — <path:line in the dependency>
DEPENDENTS
<name> — COMPATIBLE (<path:line>) | UNKNOWN (<command that would settle it>)
DROPPED AS NOT OCCURRING (<n>): <symbol>, <symbol>, …
patterns searched: <the exact greps>
NOT VISIBLE TO THIS METHOD
<reflection / DI / generated code / cross-module callers, each with what would find it>Part of mobile-ground-truth. Install it with arcturn add sitharaj88/arcturn/kits/mobile-ground-truth, then type /upgrade-impact in a session.