Repository navigation
Decision note 0017: owning fab, and how a package this project depends on is named - #18
marcos-mendez wants to merge 3 commits into
Conversation
…amed The build host ran fab 1.1.1+keel2, built and installed at 17:14 on 2026-09-27 from a commit that reached the default branch at 19:58, with no tag on either packaged version. A layer manifest records the builder as a version string and nothing else, so core.manifest's fab_version 1.1.1+keel1 named no commit, and the project's rebuildability claim did not hold for the one thing every image is built with. The note records what was measured before it was written, including two things the first report of this got wrong: the running files were not divergent from git, and the changelog entry did exist and had merged nine hours earlier. What was actually broken is that a version string was the only provenance there was, and that the string said we had patched somebody else's release. The decision is that a package this project depends on and modifies becomes a Keel package with a version we choose: keel-fab 0.1.0, plain, no +keelN. The note argues the three axes separately, because they are separate: the repository keeps its upstream name per 0006, which rules on repositories and not on package names; the version scheme follows the boundary apt/lib/build.sh already implements, which the keel prefix is what selects; and every command name, path and python module stays byte identical, which the 380 call sites decide rather than a preference. None of them reads the Debian package name. It also records the first Provides/Replaces/Conflicts triple in this organization's packaging with the reason for each field, since tracker#13 will need it and should not copy the fields without reading why fab's Provides does almost nothing while theirs will do real work. The trap is new and cost a rebuild to find: debhelper keys its per-package files on the binary package name, dh_python3 finds a private directory the same way, and a rename silently drops whatever was being picked up by name. Only building both packages and comparing them found it.
The note argued 0.1.0, matching the scheme every package this project already owns. The changelog gate wired up in Keel-Linux/fab#9 refused it on its first run, and it was right: dpkg --compare-versions 0.1.0 gt 1.1.1+keel2 is false, require-changelog compares exactly that way, and reprepro and dpkg-genchanges read a changelog as one monotonic series too. A rename does not give the file a fresh start. The note now carries the measurement and the rule it produces: a package that becomes ours takes the next version above the highest it has already published, and only a package with no predecessor starts at 0.1.0. That is the part the next package to move needs, and it was not obvious enough to get right by reasoning. The trap entry gains the same lesson as a second paragraph, since it has the same root, a rename, and was found the same way, by a gate rather than by reading. Also the precise comparison numbers: all 28 paths the fab 1.1.1+keel2 on the build host ships are present in keel-fab 2.0.0 and 26 are byte identical, with the two differing being /usr/bin/fab by the get_version change and the rtupdate file by the package name inside it.
Review of #18Reviewed alongside Keel-Linux/fab#9, where the implementation findings are. This comment is about the note as a record: whether it argues its choices, and whether what it states is true. It argues rather than records. "Why 2.0.0 and not 0.1.0" carries the measurement that refused the first answer and the rule it generalises to. "Why The findings below are all in the same place: the note is precise about everything it measured itself and loose about the two or three things it inherited. HIGH. The
|
Review of #18 found the relationships table stating a mechanism that is false on the build host: apt resolves "apt-get install fab" to a real fab in an enabled archive over any virtual provider, and TurnKey's archive offers one at 999. Reproduced on 2026-09-29 in a scratch apt tree: keel-fab 2.0.0 installed, a real fab served over http, and apt removes keel-fab to install it. The fix the review proposed, "Pin: origin \"\"", does not close it. It passed a test built on a file: repository, where the host name is empty; against the same package served over http it blocks nothing. Pinning the real package by its archive, "Pin: release o=turnkeylinux" at -1, does, and leaves the way back to fab_1.1.1+keel2_all.deb working. The build host's TurnKey Release files carry Origin: turnkeylinux. Also: the Conflicts row still named 0.1.0; the package comparison is restated over the full file set (35 and 37 entries, 26 identical, 8 renamed by debhelper, 2 new); the tag rule is described as it now is (annotated, reachable, a floor, required on the default branch); the remote-name fragility of the native classification is stated; the stale-ref diagnosis is sharpened; the call-site counts carry their provenance; "lintian is quiet" was not measured and is gone.
|
fad3160: the |
Closes #17.
Decision note 0017, and only 0017: 0014, 0015 and 0016 are concurrent work, so the number was taken deliberately rather than as "the next free one". 0011 stays a gap, per the record in #11.
What it records
The maintainer's decision of 2026-09-28 in Keel-Linux/fab#8, and the reasoning that decides the shape rather than assuming it. The rule it settles outlives fab: a Debian package this project depends on and modifies becomes a Keel package with a version this project chooses, not upstream's version with a
+keelNsuffix. For fab that iskeel-fabat2.0.0.Implementation is Keel-Linux/fab#9, which closes fab#8 and fab#7. Not merged, and the build host has not been converted.
Three things the note adds beyond the issue
It corrects the record on what
1.1.1+keel2was. Keel-Linux/fab#7 states that the version exists in no commit and implies the installed files might diverge from git. Both were measured and both are wrong. Every file the package ships is in git: comparing the extracted.debagainste610377, 22 of 25 byte identical and the three that differ do so only indh_python3's shebang normalisation. And the changelog entry merged as fab#6 at 2026-09-27T19:58:53Z, ten hours before fab#7 was filed;git log -- debian/changelogonmasterhas returned two commits since then. fab#7 was read from a stale ref: the build host clone had not fetched since before fab#6, so itsorigin/masterpredates the entry while itsHEADcarries it.That matters for the note because it changes what the defect is. It was never the missing entry. It was that a version string was the only provenance there was, and neither packaged version was tagged at all, so
core.manifest'sfab_version 1.1.1+keel1named no commit. The note says that plainly instead of repeating the issue.It separates three axes that were being conflated. The repository name (0006 rules on it, keeps
fab, and stands), the Debian package name (renamed, and this is the first divergence between the two, so it is stated rather than inferred), and the command names (unchanged, decided by 380 call sites of which not one reads the package name). It also states why decision 0015 does not reach these commands: a build tool is not operator facing, and extending 0015 to it would rename 380 call sites to no operator's benefit inside a change whose point is that the build host keeps building.It argues the name from the tooling rather than from taste.
apt/lib/build.shclassifies a package as native when theSourcestarts withkeel, the clone has noupstreamremote and neitherdebian/watchnordebian/upstream/metadataexists. The fab clone already satisfied the last two, sokeel-fabmakesbin/build-packageaccept0.1.0on its own and the+keelNguard correctly stops applying, with nobody passing--native. The rule that selects the version scheme is keyed on the prefix, so a package whose scheme is ours has to carry the prefix or the policy and the code disagree.The version number was got wrong first, and the note records how
The note argued
0.1.0, matching the scheme every package this project already owns starts at. The changelog gate wired up in Keel-Linux/fab#9 refused it on its first run and was right:dpkg --compare-versions 0.1.0 gt 1.1.1+keel2is false,require-changelogcompares exactly that way, andrepreproanddpkg-genchangesread a changelog as one monotonic series too. A rename does not give the changelog a fresh start.So the note carries the rule the next package to move needs: a package that becomes ours takes the next version above the highest it has already published, chosen by what the change means, and only a package with no predecessor starts at 0.1.0. For fab that is
2.0.0, which also stops0.xclaiming that the thing building every layer in production is pre-release.This is recorded rather than quietly corrected because it was not obvious by reasoning; a gate caught it, and the gate only existed because the same pull request wired it up.
The
Provides/Replaces/Conflictsreasoning, for tracker#13's benefitThis is the first such triple in the organization's packaging, so the note records what each field is for.
Conflictsis load bearing andReplaceshands the paths over.Providessatisfies a dependency on the name and nothing more: it does not protect an install by name while TurnKey's archive offers a realfab(apt removeskeel-fabfor it, reproduced 2026-09-29), and a fab plan cannot resolve it at all (tkldev#4). The negative pinPackage: fab/Pin: release o=turnkeylinux/Pin-Priority: -1is what protects the host;Pin: origin ""only matches a local repository and does not. So apt#15 is a prerequisite of the conversion, and tracker#13 needs the same pin per replaced name.A versioned
Provides: fab (= 1.1.1+keel2)is recorded as considered and rejected: it would satisfy a versioned dependency that exists nowhere, at the cost of writing upstream's version number back into the package whose point is not to carry one.Also in this pull request: one new trap
docs/traps.mdgains "Renaming a Debian package drops whatever debhelper found by its name". debhelper keys.install,.linksand.docson the binary package name, anddh_python3finds a private python directory the same way, so a rename silently drops whatever was being picked up by name and the failure surfaces at first use. Naming the directory back has its own trap:dh_python3 <dir>processes that directory instead of its default pass, and the default pass is what moves a module off/usr/lib/python3.13/dist-packagesonto the version independent path, so one call with the argument trades a missing registration for a module pinned to one python version. Both calls are needed.It was found by building the old and new packages in a container and diffing them. Every static check on
debian/passed throughout and said nothing, which is the part worth writing down. The entry carries the version lesson as a second paragraph, since it has the same root, a rename, and was likewise found by a tool rather than by reading.The other trap is left alone on purpose. #13 is adding "two machines answer to tkldev, and they run different fab", and this work hit that trap in its other form: a claim measured from the wrong clone reads exactly like one measured from the wrong machine. The note says so and says the fix needs one word added, "name the clone and its head, not only the machine", but leaves the amendment to #13 so the two do not collide in the same file.
Test plan
Date,Status,## Decision, the three part justification of brief section 10,## Consequences. It also carries## What this does not decide,## Traps found while writing thisand## Implementation, following 0016.docs/traps.md. No index to update;docs/decisions/has none.keel-faband2.0.0, which is the part fab#9 cannot land without.Related
fab_commitin the manifest, after fab#9.This repository ships no package and has no
package / changeloggate, so there is no changelog entry to add and no checks are reported on the branch.