Repository navigation
Build as keel-fab, with a version this project chose - #9
marcos-mendez wants to merge 9 commits into
Conversation
Two suites carried the same twenty lines and a third was about to make it three. The handbook records copying a test library instead of sharing it as something this project did wrong and would do again unless it was written down, so the helpers move to tests/tap.sh and the suites source it. No check changes: source-date-epoch is 19 of 19 and units 56 of 56, as before.
… from A layer manifest records the builder as a version string and nothing else: core.manifest on the mirror carries "fab_version 1.1.1+keel1". That string is provenance only if it resolves to a commit. On 2026-09-27 it did not. The package installed on the build host, fab 1.1.1+keel2, was built at 17:14 from a commit that reached the default branch at 19:58 and was never tagged, so for those hours the machine that builds every layer ran a version no clone could name a commit for. bin/check-release-tags states the rule: every changelog entry whose distribution is not UNRELEASED is a release, and every release below the newest must have a tag <source>/<version> whose tree carries that version at the top of its changelog. The newest is exempt, being the one a pull request is proposing. The source name comes from the entry, so a version released before a rename is checked under the name it was released as. The other direction needs nothing new: git describe on a commit says which release it belongs to, and that tag's changelog says the version a manifest would record. tests/release-tags.sh drives the script against repositories it builds under mktemp -d, so the suite does not depend on this repository's own tags: 15 of 15 checks, covering each verdict and each of the three exit codes.
A +keelN suffix on somebody else's version string says we patched their thing. The running 1.1.1+keel2 is what that half measure produced: a version invented at packaging time, on a machine, for a repository whose default branch did not carry it until three hours later. The source and binary package are now keel-fab at 0.1.0, the plain scheme every package this project owns already uses (keel 0.1.0, keel-transition 0.1.0, keel-archive-keyring 0.1.0). The repository keeps its upstream name and its upstream history, per decision 0006: the rename is of the package, not of the fork. The apt tooling agrees without being changed. bin/build-package classifies a package as native when the Source starts with keel, the clone has no upstream remote and nothing records an upstream. All three now hold, so the +keelN guard correctly stops applying to this package instead of having to be overridden. Provides, Conflicts and Replaces fab. There is no reverse dependency on fab anywhere in the organization, so Provides is not what the callers need; it is there for the two places that install the package by name, the tkldev recipe's plan and tkldev-setup. Conflicts and Replaces are what matter: the two packages ship the same paths and must never be installed together. Nothing a caller can see is renamed. Roughly 380 call sites across this organization name fab-chroot, fab-apply-overlay, FAB_PATH, $(FAB_PATH)/common or /usr/share/fab, in buildtasks, in the shared makefiles and in every recipe Makefile, and not one of them reads the Debian package name: they are PATH lookups, make variables and filesystem paths. So /usr/bin/fab, the nine fab-* aliases, /usr/share/fab and the fablib module keep their names exactly. What does have to move is the three debhelper files, which are keyed on the binary package name. A rename that leaves debian/fab.install behind builds a package with no /usr/bin/fab* and no /usr/share/fab, and says so nowhere: the failure surfaces at the first fab-chroot of the next build. Every shipped path is a check in tests/packaging.sh for that reason, each of the nine aliases on its own. fab --version no longer runs "apt-cache policy fab". That asked about whatever package is called fab on the machine rather than about itself, so after this rename it would answer "(none)", and bt-layer writes the answer into every layer manifest as fab_version. debian/rules records the changelog version at /usr/share/fab/version and fablib/version.py reads it back, which is also the right answer on a host that installed the .deb from a file and has no archive entry at all. tests/packaging.sh: 34 of 34.
This repository had only tests.yml, calling the shared coverage workflow. It never called the organization's require-changelog gate, which is the direct cause of #7: pull requests #4 and #5 both changed share/product.mk, a path this package ships, and neither added a changelog entry. The version was bumped at packaging time instead. The gate has existed in Keel-Linux/.github throughout and 15 repositories call it. This one now does, with the defaults, since debian/changelog is where its version lives. The check is "package / changelog". release-tags runs bin/check-release-tags with a full checkout, because the tags are the thing under test and the default shallow fetch brings none.
tests/coverage.sh runs source-date-epoch, units, packaging and release-tags, and counts the checks of all four: 124 of 124, 100 percent, measured 2026-09-28. The gate stays at 100. COVERAGE.md records why packaging.sh asserts each shipped path separately, and why fablib/version.py is driven directly rather than through the fab entry point, which imports chroot and python3-debian and cannot run on the coverage runner.
Found by building the package, which no assertion about debian/ could have caught. dh_python3 recognises a private python directory by the binary package name, so while the package was called fab it picked up /usr/share/fab on its own. Renaming the package to keel-fab silently dropped the byte-compilation registration in /usr/share/python3/runtime.d and the shebang rewrite of the two scripts under /usr/share/fab. Naming the directory is the fix, but a single call with the argument replaces the default pass rather than adding to it, and the default pass is what moves fablib from /usr/lib/python3.13/dist-packages, where pybuild put it, to the version independent /usr/lib/python3/dist-packages. So one call with the argument trades one silent divergence for a worse one. Both calls are needed. All three variants were built in a debian:trixie container and compared against the fab 1.1.1+keel2 .deb the build host has installed. With both calls, keel-fab 0.1.0 ships the same 26 paths: 24 byte identical, including all nine /usr/bin/fab-* symlinks and share/product.mk, with /usr/bin/fab differing only by the get_version change and the rtupdate file only by the package name inside it, plus the two new files fablib/version.py and /usr/share/fab/version. Nothing was built, installed or changed on the build host. tests/packaging.sh: 35 of 35. tests/coverage.sh: 125 of 125, 100 percent.
…enamed The first version proposed was 0.1.0, matching the scheme every package this project already owns: keel 0.1.0, keel-transition 0.1.0, keel-archive-keyring 0.1.0. The changelog gate wired up in this same branch refused it, correctly, and that is the first thing the gate has ever caught here. dpkg --compare-versions 0.1.0 gt 1.1.1+keel2 is false. require-changelog compares the proposed top version against the base's exactly that way, and reprepro and dpkg-genchanges read the file as one monotonic series too, so renaming the source does not start the numbering over. dpkg-genchanges was already saying so as a warning on the 0.1.0 build. The reset was also the wrong signal. The other Keel packages start at 0.1.0 because they had no predecessor; this code has been building every layer in production since before it was ours, and 0.x would claim it is pre-release. 2.0.0 sorts above every upstream 1.x and above both +keelN builds, carries no suffix, and says a major break: the name, the numbering and the ownership all change at once. tests/packaging.sh now asserts the ordering against the entry below, with the measurement that produced the rule in the comment, so the next person renaming a source package reads it here rather than from a red check. Rebuilt and recompared in the container: keel-fab 2.0.0 against the fab 1.1.1+keel2 installed on the build host has all 28 of its paths, 26 byte identical, the two that differ being /usr/bin/fab by the get_version change and the rtupdate file by the package name inside it, plus two new files. Nothing is missing, and dpkg-genchanges no longer warns. tests/packaging.sh: 36 of 36. tests/coverage.sh: 126 of 126, 100 percent.
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 #9Read-only throughout: nothing was built, installed or changed on the build host, no lock was taken. The package was built independently in a throwaway First, the thing #7 got wrongConfirmed, and the correction in this pull request is the right outcome.
The cause is one step more specific than "the build host's own The
Everything below is about what the change does next, ordered by severity. HIGH 1.
|
| Symbol | Table | Measured |
|---|---|---|
fab-chroot |
~100 | 116 |
fab-apply-overlay |
34 | 39 |
fab-plan-resolve |
25 | 28 |
FAB_PATH |
~256 | 298 |
FAB_ARCH |
~92 | 111 |
/usr/share/fab |
9 | 31 |
import fab |
0 | 0 |
Low by 10 to 20 percent throughout and by 3.4 times for /usr/share/fab. Undercounting is the safe direction for a claim of the form "none of these reads the package name", so the conclusion is unaffected, but the prose says "roughly 380 references" while the table sums to 631. Say which tree and which exclusions produced the numbers, or round them off.
MEDIUM 12. The coverage number is a pass rate
tests/coverage.sh:37-40 computes the share of checks that pass, so it reads 100 whenever the suites are green and can only fall when a test fails. Adding packaging and release-tags to suites= therefore does not measure whether their branches are exercised; the claim rests entirely on the header's hand enumeration. That is pre-existing and honestly described, but docs/traps.md already carries "100 percent line coverage on the same file" as something that misled this project once, and the two new suites are the first here where a branch can go unexercised without the number moving. Worth a sentence in COVERAGE.md.
LOW
- The count is 126, not 125.
19 + 56 + 36 + 15, and I ran all four:1..19,1..56,1..36,1..15, zeronot ok. The Measured table says 126 and the test plan says 125. - "nine hours before The running fab version does not exist in this repository #7 was filed" is 10 hours 7 minutes.
19:58:53Zto06:06:20Z. - "the build host's own
master, whichgit branch -vvthere still reports asbehind 4" is behind 4 of aorigin/masterthat is itself stale at16730a5; against the realmasterit is behind 6. The conclusion is right either way, and the sharper statement is that the host has not fetched since before Package as 1.1.1+keel2 so the build host gets the unit slots #6. - "
shellcheck -xclean on every file this branch adds or touches" is true at warning level and above.tests/units.shandtests/source-date-epoch.sh, both touched here, carry 6 and 9 note-levelSC2317. Identical counts onmaster, so nothing was introduced; the claim just wants "no warnings or errors". debian/rules:15hardcodesdebian/keel-fab/. It fails loudly if the name changes again, which is acceptable, but$(shell dh_listpackages)costs nothing.- One operator hazard worth a line in the runbook.
aptcan never co-install the two: with--no-removeit stops atE: Packages need to be removed but remove is disabled.dpkg -i --force-conflicts --force-overwritecan, and becauseReplacesis one-directional the result is thatkeel-fabkeeps ownership of/usr/bin/faband all nine aliases even thoughfabunpacked second. Removingkeel-fabthen deletes them, leavingfab 1.1.1+keel2installed,dpkg -V fabexiting 0, and no/usr/bin/faband no/usr/bin/fab-chrooton the machine. So: never reach for--force-conflictshere, and verify withdpkg -S /usr/bin/fabrather thandpkg -V.
On the conversion itself
The mechanics are sound and I checked all three directions in a container.
- Forward, no extra flags:
apt-get install ./keel-fab_2.0.0_all.debremovesfab, installskeel-fab, and every path including the nine aliases ends up owned bykeel-fab. - Back, no extra flags and no
--allow-downgradesneeded since the names differ:apt-get install /root/src/fab_1.1.1+keel2_all.debremoveskeel-faband restores/usr/bin/fab-chroot. - Failing halfway does leave a window with no fab at all, but it is recoverable offline from the kept
.deb, which is the property that matters.
So the reversibility claim holds. What is not yet true is that it is safe to schedule: HIGH 1 has to be closed in apt#15 first, with the negative pin and not only the widened stanza, and HIGH 2 needs tkldev/plan/main filed before the archive ever drops fab.
Verdict
No CRITICAL. Four HIGH, none of them in the diff itself: the packaging is right, the dh_python3 work is right and well evidenced, the version choice is right and the test pins it, and #7's premise really was wrong. The HIGH items are in the deferral reasoning and in the reach of the new gate, and three of the four are a few lines each.
Warning.
…ree on one version Four findings from review, all in the reach of the new gate or in what the package says about itself rather than in the packaging. The newest release was exempt from the tag rule forever, not just on a pull request. Nothing revoked the exemption, so keel-fab 2.0.0 would have merged green, been built, installed and written into every manifest as fab_version while git rev-parse keel-fab/2.0.0 failed: issue #7's hole, one version deeper. The workflow now runs the check twice, and the default branch run passes --require-newest. Push the release tag with the merge, as was done for fab/1.1.1+keel1 and fab/1.1.1+keel2. An UNRELEASED entry on top also passed the exemption down to the newest real release, indefinitely. The exemption belongs to the entry at the top of the file and to nothing else, which is what the code now says. The rule accepted a lightweight tag on a commit outside the branch. That matters because the reverse direction it promises is git describe --match '*/*', and git describe refuses a lightweight tag outright, so the half CI enforced was the weaker of the two. A release tag must now be annotated and an ancestor of HEAD; both fixtures that prove it build the failing case. The rule also had no floor, so a later merge from upstream bringing real upstream entries into the changelog would have demanded fab/1.1.0 and fab/1.0.3 forever, and upstream tags those v1.1.0 and v1.0.3. --since is the floor and CI passes 1.1.1+keel1, the first version this project released. The header records that an epoch can never satisfy the rule, since refs/tags/<source>/1:2.0.0 is not a legal refname. pyproject.toml was never touched, so the built package told importlib.metadata it was "fab 1.1.0" while dpkg called it keel-fab 2.0.0 and /usr/share/fab/version said 2.0.0: three answers to one question, and the next person to fix version reporting would have reached for the wrong one. All four now agree and the suite asserts it. The version override is FAB_VERSION_FILE rather than FAB_SHARE_PATH. FAB_SHARE_PATH is a build variable; product.mk and turnkey.mk both set it with ?= and neither exports it, so no build misfires today, but one exported FAB_SHARE_PATH pointing at a checkout was enough to make bt-layer record fab_version unknown on every image built afterwards. A check now refuses to let any build variable back into that lookup. debian/rules derives the staging directory from dh_listpackages instead of hardcoding it. Rebuilt and recompared over the full file set, with nothing excluded this time: 35 entries in the old package and 37 in the new, 27 at the same path of which 26 are byte identical, 8 renamed by debhelper keying on the package name, 2 new, nothing dropped. The earlier "28 paths, 26 identical" quietly left out the dist-info and usr/share/doc files, and all three unmentioned changes were inside what it left out. tests/release-tags.sh: 27 of 27. tests/packaging.sh: 39 of 39. tests/coverage.sh: 141 of 141, 100 percent.
The comment above the release-tags job carried its first paragraph twice, the old text left in place when the two invocations were added, and the old copy still said the newest entry is exempt, which is now true on a pull request only.
|
HIGH 3 and 4 are fixed in 6a1f93c (reproduced: an untagged newest release fails under |
Closes #8. It also closes #7, in the same pull request rather than a separate one: #7 asks for a changelog entry that makes the running version exist in git, for the
require-changelogwiring, and for provenance checkable from a manifest and a git tag. The first is already true and was true before #7 was filed (below); the other two are here. There is nothing left in #7 that this does not do, and the constraint is one pull request per repository.What
1.1.1+keel2actually is, measured before anything was writtenThe installed package on the build host is byte for byte
/root/src/fab/../fab_1.1.1+keel2_all.deb, sha2561b8ee5bcc2a9e91596f521abe561f4c69a4c1b92e1ee014d952eabd8b6186adf, built there on 2026-09-27 at 17:14:56 UTC./var/lib/dpkg/info/fab.md5sumsis identical to the.deb's ownmd5sums, anddpkg -V fabis clean.It was built from
/root/src/fabat commite610377with a clean worktree. Every file it ships is in git. Comparing the extracted.debagainst that checkout, file by file: 22 of 25 byte identical, and the three that differ (/usr/bin/fab,share/make-release-deb.py,share/turnkey-version.py) differ only indh_python3's shebang normalisation,#!/usr/bin/python3to#! /usr/bin/python3.product.mkisa06bfe03, as #7 records. There is nothing in the running fab that is not in this repository.And the changelog entry exists.
e610377is debian: changelog 1.1.1+keel2, the unit slots the build host needs, and it merged tomasteras #6 at 2026-09-27T19:58:53Z, ten hours before #7 was filed at 2026-09-28T06:06:20Z.git log --oneline -- debian/changelogonmastertoday returns two commits, not one. The measurement in #7 read a stale ref: in the build host cloneHEADise610377, butremotes/origin/masteris16730a5, the #5 merge, because the clone had not fetched since before #6.So the defect is not the one #7 describes, and it is worse in one respect and better in another:
1.1.1+keel2appears nowhere in the historymaster, merged in #6 before #7 was filedshare/product.mk, a path this package shipsgit tag -lcarried only upstream'sv0.5..v1.1.1The last row is what was actually unfixed, and it is why
core.manifest'sfab_version 1.1.1+keel1named no commit. Two annotated tags now exist, pushed ahead of this branch so the new check passes:fab/1.1.1+keel1onb07a733andfab/1.1.1+keel2one610377, each recording what was built from it and that it was tagged after the fact.One unrelated finding, for whoever owns
docs/build-host.md: it records the+keel1.debas sha256f4bf09be9535…, and the file on the host and its own.changesboth say1dc54a20acc2….The shape, and why
The package becomes
keel-fabat2.0.0. The repository staysfab. Decision 0006 rules on repository names, and infrastructure keeps its upstream name; this renames the Debian package, which is a different axis, and the fork, its history and its upstream compatibility are untouched. No+keelN.2.0.0and not0.1.0, and the changelog gate is what settled it.0.1.0was proposed first, matching the scheme every package this project owns already starts at:keel0.1.0,keel-transition0.1.0,keel-archive-keyring0.1.0. The gate wired up in this same branch refused it on its first run, which is the first thing it has ever caught here.dpkg --compare-versions 0.1.0 gt 1.1.1+keel2is false;require-changelogcompares the proposed top version against the base's exactly that way,repreproanddpkg-genchangesread a changelog as one monotonic series too, anddpkg-genchangeswas already warning on the 0.1.0 build. A rename does not give the changelog a fresh start. The reset was the wrong signal as well: the other Keel packages start at 0.1.0 because they had no predecessor, while this code has been building every layer in production since before it was ours.2.0.0sorts above every upstream 1.x and both+keelNbuilds, carries no suffix, and says what happened.tests/packaging.shnow asserts the ordering with that measurement in the comment.The apt tooling agrees without being changed, which is the strongest argument for the name.
apt/lib/build.shclassifies a package as native when theSourcestarts withkeel, the clone has noupstreamremote, and neitherdebian/watchnordebian/upstream/metadataexists. This clone has noupstreamremote and neither file, so all three now hold andbin/build-packagewill accept0.1.0on its own. The+keelNguard correctly stops applying instead of having to be overridden with--native.Provides: fab,Conflicts: fab,Replaces: fab, all unversioned.apt-cache rdepends fabon the build host is empty and nodebian/controlin the organization depends onfab, soProvidessatisfies nothing here. It does not protect an install by name: apt prefers a realfabin an enabled archive (TurnKey's, at 999 on the build host) and removeskeel-fabfor it, and a fab plan cannot resolve a virtual name at all (tkldev#4). What protects the host is the negative pinPackage: fab/Pin: release o=turnkeylinux/Pin-Priority: -1(notPin: origin "", which only matches a local repository), which makes apt#15 a prerequisite of the conversion.ConflictsandReplacesare the load-bearing pair: the two packages ship the same paths and must never be co-installed. A versionedProvides: fab (= 1.1.1+keel2)was considered and rejected: it would satisfy a versioned dependency onfab, of which there are none anywhere, at the cost of writing upstream's version number back into a package whose point is not to carry it.The call sites decide the command names, and they say keep them
Counted across the organization (about 700 references, measured in review over 40 repositories; the first count was 10 to 20 percent lower), and not one of them reads the Debian package name: they are
$PATHcommand lookups, make variables and filesystem paths, and Debian imposes no relation between a package's name and the paths it ships.fab-chrootPATHfab-apply-overlayPATHfab-plan-resolvePATHfab-apply-removelistPATHfab-apply-patch,fab-install,fab-cpp,fab-query,fab-plan-annotatePATHfab-investigate,fab-rewindPATHFAB_PATH/turnkey/fab-keelFAB_ARCH$(FAB_PATH)/common/usr/share/fabFAB_SHARE_PATHimport fabfablib, and always wasSo every command name, every path and the
fablibmodule stay exactly as they are. Renaming the binaries is a much larger change and is not in here. The nine/usr/bin/fab-*aliases are each asserted separately intests/packaging.sh, because the one thing a rename really does break isdebian/fab.install,debian/fab.linksanddebian/fab.docs: debhelper keys them on the binary package name, and a rename that leaves them behind builds a package with no/usr/bin/fab*and no/usr/share/fabwhile saying nothing, with the failure surfacing at the firstfab-chrootof the next build.Nine sites do read the package name. Eight are listed under "not in this pull request" below. The ninth was inside this repository and is fixed here:
fab --versionranapt-cache policy fab, which asks about whatever package is calledfabon the machine rather than about itself. After this rename it would answer(none), measured on the build host against a real virtual package.bt-layer:214writes that answer into every layer manifest asfab_version, so it would have written(none)into the provenance record of every image built afterwards.debian/rulesnow records the changelog version at/usr/share/fab/versionandfablib/version.pyreads it back, which is also the right answer on a host that installed a.debfrom a file and has no archive entry either way.Which fab built this layer, in both directions
A manifest records the builder as a version string and nothing else, so the string is provenance only if it resolves to a commit.
fab_version 1.1.1+keel1becomesgit rev-parse fab/1.1.1+keel1.bin/check-release-tagsmakes that total: every changelog entry whose distribution is notUNRELEASEDis a release, and every release below the newest must have a tag<source>/<version>whose tree carries that version at the top of its changelog. The newest entry is exempt, being the release a pull request is proposing. The source name comes from the entry, so the two versions released before the rename are checked asfab/…and notkeel-fab/….git describe --match '*/*'on a commit names its release, and that tag's changelog gives the version a manifest would record. No new machinery.Recording a commit in the manifest as well is worth doing, and is not needed now.
keelalready keeps any manifest key it does not know and writes it back unchanged (keel/docs/layers.md, "Optional fields"), so afab_commitfield costs one line atbt-layer:214and nothing at all inkeel. What it buys over the tag is the case the tag cannot cover: a.debbuilt from an untagged or dirty tree, which is exactly what happened on 2026-09-27. The tag invariant closes that procedurally and the CI job keeps it closed, sofab_commitis belt and braces rather than a prerequisite. It is abuildtaskschange, so it is a second pull request in that repository, and it is filed as Keel-Linux/buildtasks#12 rather than bundled here.Converting the build host, and the way back
Nothing was built, installed or changed on the build host. Access there was read only throughout, no lock was taken, and no layer was published or rebuilt. The package was built in a throwaway
debian:trixiecontainer to provedebian/rulesworks and to compare the result against what the host runs.The conversion is one command and is reversible, because
fab_1.1.1+keel2_all.debstays in/root/srcand nothing deletes it:Verify after either direction with
fab --version,dpkg -L keel-fab | grep /usr/bin, and onefab-chrootin a scratch tree.Two things to know before scheduling it.
/etc/apt/preferences.d/keel-fabpinsPackage: fab/Pin: version 1.1.1+keel1*, and the installed version is1.1.1+keel2, so that pin matches nothing today and only Debian version ordering is keeping the local build in place over upstream's1.1.1at priority 999; it needs fixing whether or not this lands. Anddocs/build-host.mdsections 2 and 3 describe the package and the pin and will need the new name.Measured
126 of 126, 100 percent. The gate stays at 100. The TAP helpers moved to
tests/tap.shwhen the third suite wanted them; the handbook records copying a test library instead of sharing it as something this project did wrong and would do again unless written down.What no assertion about
debian/can prove is that the built package is the same package, so that was measured, over the full file set.keel-fab 2.0.0against thefab 1.1.1+keel2installed on the build host: 35 entries old, 37 new; 27 at the same path, 26 byte identical (all nine/usr/bin/fab-*symlinks andshare/product.mkamong them;/usr/bin/fabdiffers by theget_versionchange alone); 8 renamed by debhelper keying on the package name (fourdist-infofiles, three underusr/share/doc,runtime.d/fab.rtupdate); 2 new,fablib/version.pyand/usr/share/fab/version. Nothing dropped, anddpkg-genchangesno longer warns.That comparison is also what caught the one real regression in this change, which no reading of
debian/would have.dh_python3finds a private python directory by the binary package name, so while the package was calledfabit picked up/usr/share/fabon its own; renaming it silently dropped the byte-compilation registration and the shebang rewrite. Naming the directory fixes that, but a single call with an argument replaces the default pass rather than adding to it, and the default pass is what movesfabliboff/usr/lib/python3.13/dist-packagesonto the version independent/usr/lib/python3/dist-packages, so one call trades one silent divergence for a worse one. All three variants were built and compared; both calls are needed, anddebian/rulessays why.Not in this pull request, deliberately
Each is a different repository, so each is its own issue and its own pull request.
apt(turnkeylinux#15)fababove. 4 package-name reads intests/build-package.bats(:56,:192-194),docs/layout.mdpool path, and the native classification depending on there being noupstreamremote.buildtasks(#12)fab_commitin the manifest atbt-layer:214. Also the deadbt-img:113-118gate, which assumes afab_<ver>_all.debfilename.tkldev(#4)tkldev-setup:372installsfabby name, whichProvidesdoes not protect (see above);plan/main:3names it in a fab plan, which cannot resolve a virtual package and drops it silently. Before the archive ever dropsfab.handbookdocs/infra-recovery.md:96installsfabby name;docs/build-host.mdsections 2 to 4. At conversion time.bootstrapREADME.rst:32listsfabas a dependency;Makefile:41checks for the command, which is unaffected.require-changelog,keel-coreamong them. Audited in Keel-Linux/tracker#18, since it is common to the whole organization.handbook(turnkeylinux#18)docs/build-host.mdsections 2 and 3 at conversion time.Test plan
tests/coverage.sh 100.shellcheck -xclean on every file this branch adds or touches. The remaining findings intests/regtest.shandtests/override.share upstream's and untouched.debian:trixiecontainer and its contents were compared against the.debinstalled on the build host, path set and byte content.bin/check-release-tagspasses on this branch, withfab/1.1.1+keel1andfab/1.1.1+keel2pushed.package / changelog,release-tagsandtests / coverageall green. The first two ran here for the first time, andpackage / changelogearned its keep immediately by refusing0.1.0.keel-faband2.0.0, and schedules the conversion. Handbook decision note 0017 (Decision note 0017: owning fab, and how a package this project depends on is named handbook#18) carries the reasoning.