Symptom

Step 2 of openspec/changes/upgrade-agp-9-1-1 is “Bump to AGP 8.14.x (PR #2)” — the second of four staged hops to reach 9.1.1. On opening the step, the very first task (3.2 — “look up the latest 8.14 patch”) returns no version. Maven metadata at https://dl.google.com/android/maven2/com/android/tools/build/gradle/maven-metadata.xml (<lastUpdated>20260505135328</lastUpdated>) lists every published version since 3.0.0-alpha1 and jumps directly from 8.13.2 to 9.0.0-alpha01:

1
2
3
4
5
6
7
8
9
10
11
12
<version>8.13.0</version>
<version>8.13.1</version>
<version>8.13.2</version>
<version>9.0.0-alpha01</version>
…
<version>9.0.0</version>
<version>9.0.1</version>
<version>9.1.0</version>
<version>9.1.1</version>
<version>9.2.0</version>
<version>9.2.1</version>
<version>9.3.0-alpha03</version>

There is no 8.14.0, no 8.14.x-alpha line, and no plan to publish one — the AGP 8.x train ended at 8.13.2, and minor-numbering picked up at 9.0 to align with Android Studio’s release naming.

Root cause

When the upgrade plan was written, the author assumed the AGP cadence would publish an 8.14 line after 8.13 (the historical pattern). The spec’s Decision 1 explicitly considered and rejected the alternative “Skip 8.14 and jump 8.13 → 9.0” because it loses the “always one-minor-at-a-time” property. AGP’s actual release calendar deleted that choice — the 8.x line ended at 8.13.x, and the realised staging sequence is forced into three hops (8.12.3 → 8.13.2 → 9.0.x → 9.1.1) regardless of which alternative the design preferred.

This is a “the spec was written against an assumed external release schedule that turned out to differ” gap, not a build regression. The repo is sitting on AGP 8.13.2 (landed in PR #226), is deprecation-clean against that version per docs/lessons/2026-05-05-agp-8-13-bump.md, and is ready for the 8 → 9 cliff at the next step.

Fix

Documentation-only PR. No gradle/libs.versions.toml edit, no source or build-script change.

Sanity check on the spec-correction branch: JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 ./gradlew help --warning-mode=all is BUILD SUCCESSFUL with the same Step-1 deprecation inventory — the two AGP-internal multi-string warnings (lint-gradle:31.13.2, aapt2:8.13.2-14304508:linux) — and no repo-attributed deprecations. The full test gate and :androidApp:assembleRelease are unchanged from main (PR #226’s verification) and not re-run for this docs-only PR.

Prevention

  1. Verify the upstream release calendar before scoping a staged plan against it. When a multi-PR series is staged minor-by-minor on someone else’s release schedule, every “the next version is X” step is an assumption that the upstream project has not yet confirmed. The cost of this bug was low (one docs PR, no rework on merged code), but on a more invasive plan — e.g. one where each step refactors call sites — the same gap could mean wasted work chasing a deprecation cliff at a version that never ships. Future plans of this shape should treat “this minor will exist when we reach this step” as an open question, not a fact, and resolve it immediately before each step.
  2. Treat tasks.md as a hypothesis, not a contract. The plan document is correct only as long as the world it describes is correct. When it diverges, edit it in-place with the empirical finding (banner + struck-through sub-tasks + lessons reference) so future readers see the original intent and the correction. Silently skipping or renumbering a step erases the discovery.
  3. A “no-op” PR with a lessons entry is a real artefact, not wasted process. It is tempting to skip Step 2 entirely and roll the discovery into Step 3’s PR description. Don’t: the staged plan asserts each step is independently mergeable, and the lessons / spec edit is what makes the gap discoverable on the next major bump (10.x → 11.x will face the same upstream-cadence assumption). Every AGP staging plan from here on should re-check the Maven metadata as its first task, before branching.