Skip to content

release-infra: API migration targetVersion is unsatisfiable on the 0.7.x development line (and stable transitions cannot be authorized) #414

Open

Description

@GionaGranchelli

Summary

The API-compatibility authority cannot be satisfied truthfully on the current 0.7.x development
line. Two distinct defects sit behind one gate:

  1. Versioning seam: an ACTIVE migration entry must carry targetVersion == projectVersion,
    and projectVersion is the tramaiVersion Gradle property (0.6.0), which is also the
    published artifact version. A truthful entry for this line would target 0.7.0 and therefore
    can never be ACTIVE, while a 0.6.0 entry would record false release history.
  2. Stable policy: a stable module's dump transition cannot be authorized at all
    ("Migration entries cannot authorize stable changes"), and the 0.7.x Epics change
    :tramai-core, which is stable.

This is release-line infrastructure, not a per-PR defect: every later 0.7 epic that changes a
preview API will hit the same impossible requirement.

Mechanism (as implemented today)

  • ApiCompatibilityVerifier.ApiMigrationEntry.authorizes(...) requires all of
    module, fromSha256 == sha256(baseDump), toSha256 == sha256(committedDump), and
    targetVersion == projectVersion.
  • MaintainabilityBaselinePlugin.kt:1264 feeds that gate
    projectVersion = providers.gradleProperty("tramaiVersion") (default 0.5.0).
  • gradle.properties:8 declares tramaiVersion=0.6.0, and build.gradle.kts:177 uses the same
    property as the artifact version.
  • Contract 2 (base dump vs committed dump) applies stability policy: stable → any change FAILs;
    preview/experimental → an exact hash-bound entry is required.
  • The registry currently holds 4 entries, all targetVersion=0.5.0 — i.e. all LANDED
    history; the ACTIVE path has not been exercised since 0.5.0.

Measurements

./gradlew verify060Architecture (this check runs in neither ci.yml nor the verifyPr
graph — a structural reason the drift stayed invisible):

module                                                   stability   from -> to (sha256[:12])
:tramai-core                                             stable      7765d4477c27 -> c4f2dd78b044
:tramai-control-plane                                    preview     b73b76dea59e -> caa2782c2dae
:tramai-engine                                           preview     2be18464bc69 -> 34fa48078a3f
:tramai-orchestration                                    preview     64c1ff59baae -> beefaf0846ba
:tramai-persistence-file                                 preview     2c116948a04c -> 41dcb6ad3f7d
:tramai-persistence-jdbc                                 preview     820477f11b52 -> 48e004581e59
:tramai-scheduler                                        preview     5e1ae0be11be -> 18656b08156f
:tramai-spring-boot-starter-sovereign-ops                preview     7100484d4ea3 -> 5b5bad9d52b8
:tramai-spring-boot-starter-sovereign-persistence-jdbc   preview     c12710086064 -> 6546de47ac3d

The eight preview/experimental transitions belong to the candidate and must not be waived. The
:tramai-core stable transition is inherited and is not #407's to fix.

Questions to settle before any code changes

Q1 — How does an in-development release line declare its compatibility target?
Options seen so far:

  • a) tramaiVersion becomes 0.7.0 for the duration of the 0.7 development line (note it is also
    the published artifact version, so this is a release-versioning decision, not just a gate input);
  • b) the gate takes a separate authoritative release-target property (e.g. tramaiReleaseTarget)
    distinct from the artifact version;
  • c) the ACTIVE rule is relaxed to "targetVersion >= current project version" — explicitly
    rejected as a silent policy change, listed only so it can be ruled out on the record.

Q2 — What does stable mean across a release boundary?

  • a) frozen forever (current effect: literally any base/current difference fails);
  • b) frozen within a release line, unlocked at a deliberate release boundary;
  • c) additive allowed across 0.6 → 0.7, breaking forbidden;
  • d) something else / a per-release API decision recorded in the release plan.

The current message ("frozen for the project version") and the actual enforcement (any difference
fails) are not the same rule. If the intended rule is (a), then the 0.7 work has already violated
the declared model and the release needs an explicit API decision; if it is (b)/(c), the verifier
needs to implement it deliberately.

Constraint

Do not weaken or relax ApiCompatibilityVerifier until Q1/Q2 are decided — a gate adjusted to
make a candidate pass destroys the authority that makes API compatibility auditable. #407 will
not add entries to config/quality/api-migrations.yml under the current semantics: a 0.6.0
entry would record false release history and a 0.7.0 entry cannot be ACTIVE.

Follow-through for #407 (ordered)

  1. settle Q1/Q2 here;
  2. land the versioning/API-policy fix on the Epic;
  3. rebase 0.7.1d: governed run attribution & identity continuity #407 onto the corrected head;
  4. re-run the API verifier against the exact Epic base;
  5. add exact migration entries for whichever preview/experimental transitions the corrected policy
    requires;
  6. confirm only the explicitly inherited stable-policy item remains;
  7. fresh exact-head CI + RC, rewrite the PR body, mark ready.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions