I said a bunch of times already that I want to introduce origin tracking into apt, and have sticky origins with a list of allowed transitions.

It becomes increasingly clear that we should also remove pinning while doing so. Establishing a partial ordering for your sources that can conflict with your total ordering of them seems like an impossible effort.

But I'm not entirely sure yet. The design isn't entirely clear.

This is compatible with the implicit pinning rules we currently have:

So $source having

NotAutomatic: yes

no longer translates to priority 1 but

* /> $source (nothing may transition to it)

(/> is a strikethrough arrow)

And

NotAutomatic: yes
Butautomaticupgrades: yes

no longer to 100 but to

now -> $source

But also this gets complicated quickly if you want to say introduce

* -> o=Debian

To always allow upgrading third party packages to Debian ones.

Like our

now -> $source

rule conflicts now if "now" is also in Debian.

Oh god yes because it needs to be

(now AND $source) -> $source

Or is it meaningless because

$source -> $source

should always be true, that is transition should be reflexive.

But then

NotAutomatic

introduces non-reflexivity.

So we want our ordering to be antisymmetric and transitive but also we don't want it to have to be symmetric.
Some thoughts in https://mathb.in/80082 but very incomplete.
MathB.in - Share Mathematics with LaTeX and Markdown

It's very important that the version preference is antisymmetric, there must not be two differerent versions V!=V' where V -> V' and V' -> V. Otherwise you'd upgrade from V to V' and the next run from V' to V. Awkward!

It's also very important for sources ordering to be transitive. Imagine if your package is in sources A and C; and A->B and B->C. You want (P, A) -> (P, C) even without having P in B.

Imagine you had no transitivity. C would not be used for upgrading until B adds the package!

I think we can restore reflexivity, and hence turn V->V' into a partial ordering. Our introduction of rejection rules is annoying but they are necessary.

For example, we wanted to provide

NotAutomatic: * /> $source

and

o=UbuntuESM* /> o=Ubuntu

(ESM packages should not be replaced by newer packages in the Ubuntu repository).

But the combined relationship on versions can still be reflexive.

That is, we can also select the version to install based on pinning and then restrict *upgrades* using transitions, but this becomes a bit awkward perhaps.
@juliank Do you think about removing of repository based pinning? Or pinning in general? (I especially like to use pinning to prevent third party repos from replacing upstream packages.)

@nsc I don't quite know, I know that currently the world is flat.

Whether it's your OS repo, or the 3rd-party repos A,B,C APT picks the highest version for each package across them all.

You add repo A, it installs foo and libbar from it. You add repo B, now it picks libbar from it. Repo A never tested that!

The main goal is to ensure that the package you installed continues to receive updates from the repository you installed it from (or allowed replacements) and not others.

@nsc However in doing so we are also creating a second ordering of sources; and it's not entirely clear what should happen if you combine it with pinning.

Say you install foo from A and now you pin foo from C to 900, should we upgrade to it? foo is restricted to only upgrade from A, should pinning override that?

If you install a new package and we declared packages can migrate from A to B; should we install a version from A if we have a (lower) one in B?

@juliank ah thanks! That was helpful for my understanding!