<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dw="https://www.dreamwidth.org">
  <id>tag:dreamwidth.org,2009-05-21:377446</id>
  <title>Ian Jackson</title>
  <subtitle>Ian Jackson</subtitle>
  <author>
    <name>Ian Jackson</name>
  </author>
  <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/"/>
  <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom"/>
  <updated>2026-03-05T18:47:55Z</updated>
  <dw:journal username="diziet" type="personal"/>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:20851</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/20851.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=20851"/>
    <title>Adopting tag2upload and modernising your Debian packaging</title>
    <published>2026-02-15T13:30:42Z</published>
    <updated>2026-03-05T18:47:55Z</updated>
    <category term="dgit"/>
    <category term="debian"/>
    <category term="tag2upload"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;div style="background-color: #fff; color: #000"&gt;
&lt;h1&gt;&lt;a name="introduction"&gt;Introduction&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://wiki.debian.org/tag2upload"&gt;tag2upload&lt;/a&gt; allows authorised Debian contributors to upload to Debian simply by pushing a signed git tag to Debian&amp;rsquo;s gitlab instance, Salsa.
&lt;p&gt;We have recently &lt;a href="https://lists.debian.org/debian-devel-announce/2026/02/msg00002.html"&gt;announced&lt;/a&gt; that tag2upload is, in our opinion, now very stable, and ready for general use by all Debian uploaders.
&lt;p&gt;tag2upload, as part of &lt;a href="https://diziet.dreamwidth.org/20436.html"&gt;Debian&amp;rsquo;s git transition programme&lt;/a&gt;, is very flexible - it needs to support a large variety of maintainer practices. And it&amp;rsquo;s relatively unopinionated, wherever that&amp;rsquo;s possible. But, during the open beta, various contributors emailed us asking for Debian packaging git workflow advice and recommendations.
&lt;p&gt;This post is an attempt to give some more opinionated answers, and guide you through modernising your workflow.
&lt;p&gt;(This article is aimed squarely at Debian contributors. Much of it will make little sense to Debian outsiders.)
&lt;ul&gt;&lt;li&gt;&lt;a href="#why"&gt;Why&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#ease-of-development"&gt;Ease of development&lt;/a&gt;
&lt;li&gt;&lt;a href="#dont-fear-a-learning-burden-instead-start-forgetting-all-that-nonsense"&gt;Don&amp;rsquo;t fear a learning burden; instead, start forgetting all that nonsense&lt;/a&gt;
&lt;li&gt;&lt;a href="#properly-publishing-the-source-code"&gt;Properly publishing the source code&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#adopting-tag2upload---the-minimal-change"&gt;Adopting tag2upload - the minimal change&lt;/a&gt;
&lt;li&gt;&lt;a href="#overhauling-your-workflow-using-advanced-git-first-tooling"&gt;Overhauling your workflow, using advanced git-first tooling&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#assumptions"&gt;Assumptions&lt;/a&gt;
&lt;li&gt;&lt;a href="#topics-and-tooling"&gt;Topics and tooling&lt;/a&gt;
&lt;li&gt;&lt;a href="#choosing-the-git-branch-format"&gt;Choosing the git branch format&lt;/a&gt;
&lt;li&gt;&lt;a href="#determine-upstream-git-and-stop-using-upstream-tarballs"&gt;Determine upstream git and stop using upstream tarballs&lt;/a&gt;
&lt;li&gt;&lt;a href="#convert-the-git-branch"&gt;Convert the git branch&lt;/a&gt;
&lt;li&gt;&lt;a href="#change-the-source-format"&gt;Change the source format&lt;/a&gt;
&lt;li&gt;&lt;a href="#sort-out-the-documentation-and-metadata"&gt;Sort out the documentation and metadata&lt;/a&gt;
&lt;li&gt;&lt;a href="#configure-salsa-merge-requests"&gt;Configure Salsa Merge Requests&lt;/a&gt;
&lt;li&gt;&lt;a href="#set-up-salsa-ci-and-use-it-to-block-merges-of-bad-changes"&gt;Set up Salsa CI, and use it to block merges of bad changes&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#day-to-day-work"&gt;Day-to-day work&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#making-changes-to-the-package"&gt;Making changes to the package&lt;/a&gt;
&lt;li&gt;&lt;a href="#test-build"&gt;Test build&lt;/a&gt;
&lt;li&gt;&lt;a href="#uploading-to-debian"&gt;Uploading to Debian&lt;/a&gt;
&lt;li&gt;&lt;a href="#uploading-a-new-package-to-debian"&gt;Uploading a NEW package to Debian&lt;/a&gt;
&lt;li&gt;&lt;a href="#new-upstream-version"&gt;New upstream version&lt;/a&gt;
&lt;li&gt;&lt;a href="#sponsorship"&gt;Sponsorship&lt;/a&gt;
&lt;li&gt;&lt;a href="#incorporating-an-nmu"&gt;Incorporating an NMU&lt;/a&gt;
&lt;li&gt;&lt;a href="#dfsg-filtering-handling-non-free-files"&gt;DFSG filtering (handling non-free files)&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#common-issues"&gt;Common issues&lt;/a&gt;
&lt;li&gt;&lt;a href="#further-reading"&gt;Further reading&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h1&gt;&lt;a name="why"&gt;Why&lt;/a&gt;&lt;/h1&gt;
&lt;h2&gt;&lt;a name="ease-of-development"&gt;Ease of development&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;git offers a far superior development experience to patches and tarballs. Moving tasks from a tarballs and patches representation to a normal, git-first, representation, makes everything simpler.
&lt;p&gt;dgit and tag2upload do automatically many things that have to be done manually, or with separate commands, in dput-based upload workflows.
&lt;p&gt;They will also save you from a variety of common mistakes. For example, you cannot accidentally overwrite an NMU, with tag2upload or dgit. These many safety catches mean that our software sometimes complains about things, or needs confirmation, when more primitive tooling just goes ahead. We think this is the right tradeoff: it&amp;rsquo;s part of the great care we take to avoid our software making messes. Software that has your back is very liberating for the user.
&lt;p&gt;tag2upload makes it possible to upload with very small amounts of data transfer, which is great in slow or unreliable network environments. The other week I did a git-debpush over mobile data while on a train in Switzerland; it completed in seconds.
&lt;p&gt;See the &lt;a href="#day-to-day-work"&gt;Day-to-day work section&lt;/a&gt; below to see how simple your life could be.
&lt;h2&gt;&lt;a name="dont-fear-a-learning-burden-instead-start-forgetting-all-that-nonsense"&gt;Don&amp;rsquo;t fear a learning burden; instead, start forgetting all that nonsense&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most Debian contributors have spent months or years learning how to work with Debian&amp;rsquo;s tooling. You may reasonably fear that our software is yet more bizarre, janky, and mistake-prone stuff to learn.
&lt;p&gt;We promise (and our users tell us) that&amp;rsquo;s not how it is. We have spent a lot of effort on providing a good user experience. Our new git-first tooling, especially dgit and tag2upload, is much simpler to use than source-package-based tooling, despite being more capable.
&lt;p&gt;The idiosyncrasies and bugs of source packages, and of the legacy archive, have been relentlessly worked around and papered over by our thousands of lines of thoroughly-tested defensive code. You too can forget all those confusing details, like our users have! After using our systems for a while you won&amp;rsquo;t look back.
&lt;p&gt;And, you shouldn&amp;rsquo;t fear trying it out. dgit and tag2upload are unlikely to make a mess. If something is wrong (or even doubtful), they will typically detect it, and stop. This does mean that starting to use tag2upload or dgit can involve resolving anomalies that previous tooling ignored, or passing additional options to reassure the system about your intentions. So admittedly it &lt;em&gt;isn&amp;rsquo;t&lt;/em&gt; always trivial to get your first push to succeed.
&lt;h2&gt;&lt;a name="properly-publishing-the-source-code"&gt;Properly publishing the source code&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of Debian&amp;rsquo;s foundational principles is that we publish the source code.
&lt;p&gt;Nowadays, the vast majority of us, and of our upstreams, are using git. We are doing this because git makes our life so much easier.
&lt;p&gt;But, without tag2upload or dgit, we aren&amp;rsquo;t &lt;em&gt;properly&lt;/em&gt; publishing our work! Yes, we typically put our git branch on Salsa, and point &lt;code&gt;Vcs-Git&lt;/code&gt; at it. However:
&lt;ul&gt;&lt;li&gt;The format of git branches on Salsa is not standardised. They might be patches-unapplied, patches-applied, bare &lt;code&gt;debian/&lt;/code&gt;, or &lt;a href="https://wiki.debian.org/GitPackagingSurvey"&gt;something even stranger&lt;/a&gt;.
&lt;li&gt;There is no guarantee that the DEP-14 &lt;code&gt;debian/1.2.3-7&lt;/code&gt; tag on salsa corresponds precisely to what was actually uploaded. dput-based tooling (such as &lt;code&gt;gbp buildpackage&lt;/code&gt;) doesn&amp;rsquo;t cross-check the .dsc against git.
&lt;li&gt;There is no guarantee that the presence of a DEP-14 tag even means that that version of package is in the archive.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;This means that the git repositories on Salsa cannot be used by anyone who needs things that are &lt;em&gt;systematic&lt;/em&gt; and &lt;em&gt;always correct&lt;/em&gt;. They are OK for expert humans, but they are awkward (even &lt;a href="https://diziet.dreamwidth.org/9556.html"&gt;hazardous&lt;/a&gt;) for Debian novices, and you cannot use them in automation. The real test is: could you use &lt;code&gt;Vcs-Git&lt;/code&gt; and Salsa to build a Debian derivative? You could not.
&lt;p&gt;tag2upload and dgit &lt;em&gt;do&lt;/em&gt; solve this problem. When you upload, they:
&lt;ol type="1"&gt;&lt;li&gt;Make a canonical-form (patches-applied) derivative of your git branch;
&lt;li&gt;Ensure that there is a well-defined correspondence between the git tree and the source package;
&lt;li&gt;Publish both the DEP-14 tag and a canonical-form &lt;code&gt;archive/debian/1.2.3-7&lt;/code&gt; tag to a single central git depository, &lt;a href="https://browse.dgit.debian.org"&gt;&lt;code&gt;*.dgit.debian.org&lt;/code&gt;&lt;/a&gt;;
&lt;li&gt;Record the git information in the &lt;code&gt;Dgit&lt;/code&gt; field in &lt;code&gt;.dsc&lt;/code&gt; so that clients can tell (using the &lt;a href="https://ftp-team.pages.debian.net/dak/docs/generated/dakweb.html#module-dakweb"&gt;ftpmaster API&lt;/a&gt;) that this was a git-based upload, what the corresponding git objects are, and where to find them.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;This dependably conveys your git history to users and downstreams, in a standard, systematic and discoverable way. tag2upload and dgit are the only system which achieves this.
&lt;p&gt;(The client is &lt;code&gt;dgit clone&lt;/code&gt;, as advertised in e.g. &lt;a href="https://manpages.debian.org/testing/dgit/dgit-user.7.en.html"&gt;dgit-user(7)&lt;/a&gt;. For dput-based uploads, it falls back to importing the source package.)
&lt;h1&gt;&lt;a name="adopting-tag2upload---the-minimal-change"&gt;Adopting tag2upload - the minimal change&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;tag2upload is a substantial incremental improvement to many existing workflows. git-debpush is a drop-in replacement for building, signing, and uploading the source package.
&lt;p&gt;So, you can just adopt it &lt;em&gt;without&lt;/em&gt; completely overhauling your packaging practices. You and your co-maintainers can even mix-and-match tag2upload, dgit, and traditional approaches, for the same package.
&lt;p&gt;Start with &lt;a href="https://wiki.debian.org/tag2upload"&gt;the wiki page&lt;/a&gt; and &lt;a href="https://manpages.debian.org/testing/git-debpush/git-debpush.1.en.html"&gt;git-debpush(1)&lt;/a&gt; (ideally from forky aka testing).
&lt;p&gt;&lt;strong&gt;You &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; need to do any of the other things recommended in this article.&lt;/strong&gt;
&lt;h1&gt;&lt;a name="overhauling-your-workflow-using-advanced-git-first-tooling"&gt;Overhauling your workflow, using advanced git-first tooling&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The rest of this article is a guide to adopting the best and most advanced git-based tooling for Debian packaging.
&lt;h2&gt;&lt;a name="assumptions"&gt;Assumptions&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;p&gt;Your current approach uses the &amp;ldquo;patches-unapplied&amp;rdquo; git branch format used with &lt;code&gt;gbp pq&lt;/code&gt; and/or &lt;code&gt;quilt&lt;/code&gt;, and often used with &lt;code&gt;git-buildpackage&lt;/code&gt;. You previously used &lt;code&gt;gbp import-orig&lt;/code&gt;.

&lt;li&gt;&lt;p&gt;You are fluent with git, and know how to use Merge Requests on gitlab (Salsa). You have your &lt;code&gt;origin&lt;/code&gt; remote set to Salsa.

&lt;li&gt;&lt;p&gt;Your main Debian branch name on Salsa is &lt;code&gt;master&lt;/code&gt;. Personally I &lt;a href="https://datatracker.ietf.org/doc/statement-iab-statement-on-inclusive-language-in-iab-stream-documents/"&gt;think we should use &lt;code&gt;main&lt;/code&gt;&lt;/a&gt; but changing your main branch name is outside the scope of this article.

&lt;li&gt;&lt;p&gt;You have enough familiarity with Debian packaging including concepts like source and binary packages, and NEW review.

&lt;li&gt;&lt;p&gt;Your co-maintainers are also adopting the new approach.

&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;tag2upload and dgit (and git-debrebase) are flexible tools and can help with many other scenarios too, and you can often mix-and-match different approaches. But, explaining every possibility would make this post far too confusing.
&lt;h2&gt;&lt;a name="topics-and-tooling"&gt;Topics and tooling&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This article will guide you in adopting:
&lt;ul&gt;&lt;li&gt;tag2upload
&lt;li&gt;Patches-applied git branch for your packaging
&lt;li&gt;Either plain git merge or git-debrebase
&lt;li&gt;dgit when a with-binaries uploaded is needed (NEW)
&lt;li&gt;git-based sponsorship
&lt;li&gt;Salsa (gitlab), including Debian Salsa CI
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;&lt;a name="choosing-the-git-branch-format"&gt;Choosing the git branch format&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In Debian we need to be able to modify the upstream-provided source code. Those modifications are the &lt;strong&gt;Debian delta&lt;/strong&gt;. We need to somehow represent it in git.
&lt;p&gt;We recommend storing the delta &lt;em&gt;as git commits to those upstream files&lt;/em&gt;, by picking one of the following two approaches.
&lt;blockquote style="background-color: #eee; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Much traditional Debian tooling like &lt;code&gt;quilt&lt;/code&gt; and &lt;code&gt;gbp pq&lt;/code&gt; uses the &amp;ldquo;patches-unapplied&amp;rdquo; branch format, which stores the delta as patch files in &lt;code&gt;debian/patches/&lt;/code&gt;, in a git tree full of unmodified upstream files. This is clumsy to work with, and can even be an &lt;a href="https://diziet.dreamwidth.org/9556.html"&gt;alarming beartrap&lt;/a&gt; for Debian outsiders.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;div style="background-color: #ddf; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git merge&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Option 1: simply use git, directly, including git merge.&lt;/strong&gt;
&lt;p&gt;Just make changes directly to upstream files on your Debian branch, when necessary. Use plain &lt;code&gt;git merge&lt;/code&gt; when merging from upstream.
&lt;p&gt;This is appropriate if your package has no or very few upstream changes. It is a good approach if the Debian maintainers and upstream maintainers work very closely, so that any needed changes for Debian are upstreamed quickly, and any desired behavioural differences can be arranged by configuration controlled from within &lt;code&gt;debian/&lt;/code&gt;.
&lt;p&gt;This is the approach documented more fully in our workflow tutorial &lt;a href="https://manpages.debian.org/testing/dgit/dgit-maint-merge.7.en.html"&gt;dgit-maint-merge(7)&lt;/a&gt;.
&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Adopt git-debrebase.&lt;/strong&gt;
&lt;p&gt;git-debrebase helps maintain your delta as linear series of commits (very like a &amp;ldquo;topic branch&amp;rdquo; in git terminology). The delta can be reorganised, edited, and rebased. git-debrebase is designed to help you carry a significant and complicated delta series.
&lt;p&gt;The older versions of the Debian delta are preserved in the history. git-debrebase makes extra merges to make a fast-forwarding history out of the successive versions of the delta queue branch.
&lt;p&gt;This is the approach documented more fully in our workflow tutorial &lt;a href="https://manpages.debian.org/testing/dgit/dgit-maint-debrebase.7.en.html"&gt;dgit-maint-debrebase(7)&lt;/a&gt;.
&lt;p&gt;Examples of complex packages using this approach include &lt;a href="https://salsa.debian.org/xen-team/debian-xen"&gt;src:xen&lt;/a&gt; and &lt;a href="https://salsa.debian.org/common-lisp-team/sbcl"&gt;src:sbcl&lt;/a&gt;.
&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;h2&gt;&lt;a name="determine-upstream-git-and-stop-using-upstream-tarballs"&gt;Determine upstream git and stop using upstream tarballs&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We recommend using upstream git, only and directly. You should ignore upstream tarballs completely.
&lt;blockquote style="background-color: #eee; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Many maintainers have been importing upstream tarballs into git, for example by using &lt;code&gt;gbp import-orig&lt;/code&gt;. But in reality the upstream tarball is an intermediate build product, not (just) source code. Using tarballs rather than git exposes us to additional supply chain attacks; indeed, the key activation part of the xz backdoor attack was hidden only in the tarball!
&lt;p&gt;git offers better traceability than so-called &amp;ldquo;pristine&amp;rdquo; upstream tarballs. (The word &amp;ldquo;pristine&amp;rdquo; is even a &lt;a href="https://joeyh.name/blog/entry/upstream_git_repositories/"&gt;joke&lt;/a&gt; by the author of pristine-tar!)
&lt;/p&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;First, establish which upstream git tag corresponds to the version currently in Debian. From the sake of readability, I&amp;rsquo;m going to pretend that upstream version is &lt;code&gt;1.2.3&lt;/code&gt;, and that upstream tagged it &lt;code&gt;v1.2.3&lt;/code&gt;.
&lt;p&gt;Edit &lt;code&gt;debian/watch&lt;/code&gt; to contain something like this:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;version=4
opts=&amp;quot;mode=git&amp;quot; https://codeberg.org/team/package refs/tags/v(\d\S*)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You may need to adjust the regexp, depending on your upstream&amp;rsquo;s tag name convention. If &lt;code&gt;debian/watch&lt;/code&gt; had a &lt;code&gt;files-excluded&lt;/code&gt;, you&amp;rsquo;ll need to make a &lt;a href="#dfsg-filtering-handling-non-free-files"&gt;filtered version of upstream git&lt;/a&gt;.
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;From now on we&amp;rsquo;ll generate our own .orig tarballs directly from git.
&lt;blockquote style="background-color: #ee9; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;We need &lt;em&gt;some&lt;/em&gt; &amp;ldquo;upstream tarball&amp;rdquo; for the &lt;code&gt;3.0 (quilt)&lt;/code&gt; source format to work with. It needs to correspond to the git commit we&amp;rsquo;re using as our upstream. We &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; need or want to use a tarball from upstream for this. The &lt;code&gt;.orig&lt;/code&gt; is just needed so a nice legacy Debian source package (&lt;code&gt;.dsc&lt;/code&gt;) can be generated.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Probably, the current &lt;code&gt;.orig&lt;/code&gt; in the Debian archive, is an upstream tarball, which may be different to the output of git-archive and possibly even have different contents to what&amp;rsquo;s in git. The legacy archive has trouble with differing &lt;code&gt;.orig&lt;/code&gt;s for the &amp;ldquo;same upstream version&amp;rdquo;.
&lt;p&gt;So we must &amp;mdash; until the next upstream release &amp;mdash; change our idea of the upstream version number. We&amp;rsquo;re going to add &lt;code&gt;+git&lt;/code&gt; to Debian&amp;rsquo;s idea of the upstream version. Manually make a tag with that name:
&lt;pre class="shell-script"&gt;&lt;code&gt;git tag -m &amp;quot;Compatibility tag for orig transition&amp;quot; v1.2.3+git v1.2.3~0
git push origin v1.2.3+git&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you are doing the packaging overhaul at the same time as a new upstream version, you can skip this part.
&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;h2&gt;&lt;a name="convert-the-git-branch"&gt;Convert the git branch&lt;/a&gt;&lt;/h2&gt;
&lt;div style="background-color: #ddf; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git merge&lt;/h5&gt;

&lt;p&gt;Prepare a new branch on top of upstream git, containing what we want:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git branch -f old-master         # make a note of the old git representation
git reset --hard v1.2.3          # go back to the real upstream git tag
git checkout old-master :debian  # take debian/* from old-master
git commit -m &amp;quot;Re-import Debian packaging on top of upstream git&amp;quot;
git merge --allow-unrelated-histories -s ours -m &amp;quot;Make fast forward from tarball-based history&amp;quot; old-master
git branch -d old-master         # it&amp;#39;s incorporated in our history now&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;If there are any patches, manually apply them&lt;/strong&gt; to your &lt;code&gt;main&lt;/code&gt; branch with &lt;code&gt;git am&lt;/code&gt;, and delete the patch files (&lt;code&gt;git rm -r debian/patches&lt;/code&gt;, and commit). (If you&amp;rsquo;ve chosen this workflow, there should be hardly any patches,)
&lt;blockquote style="background-color: #cce; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;These are some pretty nasty git runes, indeed. They&amp;rsquo;re needed because we want to restart our Debian packaging on top of a possibly quite different notion of what the upstream is.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;Convert the branch to git-debrebase format and rebase onto the upstream git:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git-debrebase -fdiverged convert-from-gbp upstream/1.2.3
git-debrebase -fdiverged -fupstream-not-ff new-upstream 1.2.3+git&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you had patches which patched generated files which are present only in the upstream tarball, and not in upstream git, you will encounter rebase conflicts. You can drop hunks editing those files, since those files are no longer going to be part of your view of the upstream source code at all.
&lt;blockquote style="background-color: #ee9; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;The force option &lt;code&gt;-fupstream-not-ff&lt;/code&gt; will be needed this one time because your existing Debian packaging history is (probably) not based directly on the upstream history. &lt;code&gt;-fdiverged&lt;/code&gt; may be needed because git-debrebase might spot that your branch is not based on dgit-ish git history.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;Manually make your history fast forward from the git import of your previous upload.
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;dgit fetch
git show dgit/dgit/sid:debian/changelog
# check that you have the same version number
git merge -s ours --allow-unrelated-histories -m &amp;#39;Declare fast forward from pre-git-based history&amp;#39; dgit/dgit/sid&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;&lt;a name="change-the-source-format"&gt;Change the source format&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Delete any existing &lt;code&gt;debian/source/options&lt;/code&gt; and/or &lt;code&gt;debian/source/local-options&lt;/code&gt;.
&lt;div style="background-color: #ddf; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git merge&lt;/h5&gt;

&lt;p&gt;Change &lt;code&gt;debian/source/format&lt;/code&gt; to &lt;code&gt;1.0&lt;/code&gt;. Add &lt;code&gt;debian/source/options&lt;/code&gt; containing &lt;code&gt;-sn&lt;/code&gt;.
&lt;blockquote style="background-color: #cce; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;We are using the &amp;ldquo;1.0 native&amp;rdquo; source format. This is the simplest possible source format - just a tarball. We would prefer &amp;ldquo;3.0 (native)&amp;rdquo;, which has some advantages, but dpkg-source between 2013 (wheezy) and 2025 (trixie) inclusive &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=737634#107"&gt;unjustifiably rejects&lt;/a&gt; this configuration.
&lt;p&gt;You may receive bug reports from over-zealous folks complaining about the use of the 1.0 source format. You should close such reports, with a reference to this article and to &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1106402"&gt;#1106402&lt;/a&gt;.
&lt;/p&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;/p&gt;&lt;/div&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;Ensure that &lt;code&gt;debian/source/format&lt;/code&gt; contains &lt;code&gt;3.0 (quilt)&lt;/code&gt;.
&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;Now you are ready to do a &lt;a href="#test-build"&gt;local test build&lt;/a&gt;.
&lt;h2&gt;&lt;a name="sort-out-the-documentation-and-metadata"&gt;Sort out the documentation and metadata&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Edit &lt;code&gt;README.source&lt;/code&gt; to at least mention dgit-maint-merge(7) or dgit-maint-debrebase(7), and to tell people not to try to edit or create anything in &lt;code&gt;debian/patches/&lt;/code&gt;. Consider saying that uploads should be done via dgit or tag2upload.
&lt;p&gt;Check that your &lt;code&gt;Vcs-Git&lt;/code&gt; is correct in &lt;code&gt;debian/control&lt;/code&gt;. Consider deleting or pruning &lt;code&gt;debian/gbp.conf&lt;/code&gt;, since it isn&amp;rsquo;t used by dgit, tag2upload, or git-debrebase.
&lt;div style="background-color: #ddf; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git merge&lt;/h5&gt;

&lt;p&gt;Add a note to &lt;code&gt;debian/changelog&lt;/code&gt; about the git packaging change.
&lt;/p&gt;&lt;/div&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;git-debrebase new-upstream&lt;/code&gt; will have added a &amp;ldquo;new upstream version&amp;rdquo; stanza to &lt;code&gt;debian/changelog&lt;/code&gt;. Edit that so that it instead describes the packaging change. (Don&amp;rsquo;t remove the &lt;code&gt;+git&lt;/code&gt; from the upstream version number there!)
&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;h2&gt;&lt;a name="configure-salsa-merge-requests"&gt;Configure Salsa Merge Requests&lt;/a&gt;&lt;/h2&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;In &amp;ldquo;Settings&amp;rdquo; / &amp;ldquo;Merge requests&amp;rdquo;, change &amp;ldquo;Squash commits when merging&amp;rdquo; to &amp;ldquo;Do not allow&amp;rdquo;.
&lt;blockquote style="background-color: #ee9; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Squashing could destroy your carefully-curated delta queue. It would also disrupt git-debrebase&amp;rsquo;s git branch structure.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;h2&gt;&lt;a name="set-up-salsa-ci-and-use-it-to-block-merges-of-bad-changes"&gt;Set up Salsa CI, and use it to block merges of bad changes&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;a name="caveat---the-tradeoff"&gt;Caveat - the tradeoff&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;gitlab is a giant pile of enterprise crap. It &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/429516"&gt;is&lt;/a&gt; &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/472646"&gt;full&lt;/a&gt; &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/581752"&gt;of&lt;/a&gt; &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/581897"&gt;startling&lt;/a&gt; &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/217231"&gt;bugs&lt;/a&gt;, many of which reveal a fundamentally broken design. It is only barely Free Software in practice for Debian (in the sense that we are very reluctant to try to modify it). The constant-churn development approach and open-core business model are &lt;a href="https://mako.cc/writing/hill-free_tools.html"&gt;serious problems&lt;/a&gt;. It&amp;rsquo;s very slow (and resource-intensive). It can be depressingly unreliable. That Salsa works as well as it does is a testament to the dedication of the Debian Salsa team (and those who support them, including DSA).
&lt;p&gt;However, I have found that despite these problems, Salsa CI is well worth the trouble. Yes, there are frustrating days when work is blocked because gitlab CI is broken and/or one has to keep mashing &amp;ldquo;Retry&amp;rdquo;. But, the upside is no longer having to remember to run tests, track which of my multiple dev branches tests have passed on, and so on. Automatic tests on Merge Requests are a great way of reducing maintainer review burden for external contributions, and helping uphold quality norms within a team. They&amp;rsquo;re a great boon for the lazy solo programmer.
&lt;p&gt;The bottom line is that I absolutely love it when the computer thoroughly checks my work. This is tremendously freeing, precisely at the point when one most needs it &amp;mdash; deep in the code. If the price is to occasionally be blocked by a confused (or broken) computer, so be it.
&lt;h3&gt;&lt;a name="setup-procedure"&gt;Setup procedure&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Create &lt;code&gt;debian/salsa-ci.yml&lt;/code&gt; containing
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;include:
  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In your Salsa repository, under &amp;ldquo;Settings&amp;rdquo; / &amp;ldquo;CI/CD&amp;rdquo;, expand &amp;ldquo;General Pipelines&amp;rdquo; and set &amp;ldquo;CI/CD configuration file&amp;rdquo; to &lt;code&gt;debian/salsa-ci.yml&lt;/code&gt;.
&lt;blockquote style="background-color: #eee; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Your project may have an upstream CI config in &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;. But you probably want to run the Debian Salsa CI jobs.
&lt;p&gt;You can add various extra configuration to &lt;code&gt;debian/salsa-ci.yml&lt;/code&gt; to customise it. Consult the &lt;a href="https://salsa.debian.org/salsa-ci-team/pipeline/-/blob/master/README.md?ref_type=heads"&gt;Salsa CI docs&lt;/a&gt;.
&lt;/p&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;Add to &lt;code&gt;debian/salsa-ci.yml&lt;/code&gt;:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;.git-debrebase-prepare: &amp;amp;git-debrebase-prepare
  # install the tools we&amp;#39;ll need
  - apt-get update
  - apt-get --yes install git-debrebase git-debpush
  # git-debrebase needs git user setup
  - git config user.email &amp;quot;salsa-ci@invalid.invalid&amp;quot;
  - git config user.name &amp;quot;salsa-ci&amp;quot;
  # run git-debrebase make-patches
  # https://salsa.debian.org/salsa-ci-team/pipeline/-/issues/371
  - git-debrebase --force
  - git-debrebase --noop-ok make-patches
  # make an orig tarball using the upstream tag, not a gbp upstream/ tag
  # https://salsa.debian.org/salsa-ci-team/pipeline/-/issues/541
  - git-deborig

.build-definition: &amp;amp;build-definition
  extends: .build-definition-common
  before_script: *git-debrebase-prepare

build source:
  extends: .build-source-only
  before_script: *git-debrebase-prepare

variables:
  # disable shallow cloning of git repository. This is needed for git-debrebase
  GIT_DEPTH: 0&lt;/code&gt;&lt;/pre&gt;&lt;blockquote style="background-color: #ee9; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Unfortunately the Salsa CI pipeline currently lacks proper support for git-debrebase (&lt;a href="https://salsa.debian.org/salsa-ci-team/pipeline/-/issues/371"&gt;salsa-ci#371&lt;/a&gt;) and has trouble directly using upstream git for orig tarballs (&lt;a href="https://salsa.debian.org/salsa-ci-team/pipeline/-/issues/541"&gt;#salsa-ci#541&lt;/a&gt;).
&lt;p&gt;These runes were based on those &lt;a href="https://salsa.debian.org/xen-team/debian-xen/-/blob/master/debian/salsa-ci.yml?ref_type=heads"&gt;in the Xen package&lt;/a&gt;. You should subscribe to the tickets #371 and #541 so that you can replace the clone-and-hack when proper support is merged.
&lt;/p&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;Push this to salsa and make the CI pass.
&lt;p&gt;If you configured the pipeline filename after your last push, you will need to explicitly start the first CI run. That&amp;rsquo;s in &amp;ldquo;Pipelines&amp;rdquo;: press &amp;ldquo;New pipeline&amp;rdquo; in the top right. The defaults will very probably be correct.
&lt;h3&gt;&lt;a name="block-untested-pushes-preventing-regressions"&gt;Block untested pushes, preventing regressions&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In your project on Salsa, go into &amp;ldquo;Settings&amp;rdquo; / &amp;ldquo;Repository&amp;rdquo;. In the section &amp;ldquo;Branch rules&amp;rdquo;, use &amp;ldquo;Add branch rule&amp;rdquo;. Select the branch &lt;code&gt;master&lt;/code&gt;. Set &amp;ldquo;Allowed to merge&amp;rdquo; to &amp;ldquo;Maintainers&amp;rdquo;. Set &amp;ldquo;Allowed to push and merge&amp;rdquo; to &amp;ldquo;No one&amp;rdquo;. Leave &amp;ldquo;Allow force push&amp;rdquo; disabled.
&lt;p&gt;This means that the only way to land &lt;em&gt;anything&lt;/em&gt; on your mainline is via a Merge Request. When you make a Merge Request, gitlab will offer &amp;ldquo;Set to auto-merge&amp;rdquo;. Use that.
&lt;p&gt;gitlab won&amp;rsquo;t normally merge an MR unless CI passes, although you can override this on a per-MR basis if you need to.
&lt;p&gt;(Sometimes, immediately after creating a merge request in gitlab, you will see a plain &amp;ldquo;Merge&amp;rdquo; button. &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/429516"&gt;This is a bug.&lt;/a&gt; Don&amp;rsquo;t press that. Reload the page so that &amp;ldquo;Set to auto-merge&amp;rdquo; appears.)
&lt;h3&gt;&lt;a name="autopkgtests"&gt;autopkgtests&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ideally, your package would have meaningful autopkgtests (DEP-8 tests) This makes Salsa CI more useful for you, and also helps detect and defend you against regressions in your dependencies.
&lt;p&gt;The &lt;a href="documentation%20https://ci.debian.net/doc/"&gt;Debian CI docs&lt;/a&gt; are a good starting point. In-depth discussion of writing autopkgtests is beyond the scope of this article.
&lt;h1&gt;&lt;a name="day-to-day-work"&gt;Day-to-day work&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;With this capable tooling, most tasks are much easier.
&lt;h2&gt;&lt;a name="making-changes-to-the-package"&gt;Making changes to the package&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Make all changes via a Salsa Merge Request. So start by making a branch that will become the MR branch.
&lt;p&gt;On your MR branch you can freely edit every file. This includes upstream files, and files in &lt;code&gt;debian/&lt;/code&gt;.
&lt;p&gt;For example, you can:
&lt;ul&gt;&lt;li&gt;Make changes with your editor and commit them.
&lt;li&gt;&lt;code&gt;git cherry-pick&lt;/code&gt; an upstream commit.
&lt;li&gt;&lt;code&gt;git am&lt;/code&gt; a patch from a mailing list or from the Debian Bug System.
&lt;li&gt;&lt;code&gt;git revert&lt;/code&gt; an earlier commit, even an upstream one.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;When you have a working state of things, tidy up your git branch:
&lt;div style="background-color: #ddf; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git merge&lt;/h5&gt;

&lt;p&gt;Use &lt;code&gt;git-rebase&lt;/code&gt; to squash/edit/combine/reorder commits.
&lt;/p&gt;&lt;/div&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;Use &lt;code&gt;git-debrebase -i&lt;/code&gt; to squash/edit/combine/reorder commits. When you are happy, run &lt;code&gt;git-debrebase conclude&lt;/code&gt;.
&lt;p&gt;&lt;strong&gt;Do not edit debian/patches/&lt;/strong&gt;. With git-debrebase, this is purely an output. Edit the upstream files directly instead. To reorganise/maintain the patch queue, use &lt;code&gt;git-debrebase -i&lt;/code&gt; to edit the actual commits.
&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;Push the MR branch (topic branch) to Salsa and make a Merge Request.
&lt;p&gt;Set the MR to &amp;ldquo;auto-merge when all checks pass&amp;rdquo;. (Or, depending on your team policy, you could ask for an MR Review of course.)
&lt;p&gt;If CI fails, fix up the MR branch, squash/tidy it again, force push the MR branch, and once again set it to auto-merge.
&lt;h2&gt;&lt;a name="test-build"&gt;Test build&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An informal test build can be done like this:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;apt-get build-dep .
dpkg-buildpackage -uc -b&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ideally this will leave &lt;code&gt;git status&lt;/code&gt; clean, with no modified or un-ignored untracked files. If it shows untracked files, add them to &lt;code&gt;.gitignore&lt;/code&gt; or &lt;code&gt;debian/.gitignore&lt;/code&gt; as applicable.
&lt;p&gt;If it dirties the tree, consider trying to make it stop doing that. The easiest way is probably to build out-of-tree, if supported upstream. If this is too difficult, you can leave the messy build arrangements as they are, but you&amp;rsquo;ll need to be disciplined about always committing, using git clean and git reset, and so on.
&lt;p&gt;For formal binaries builds, including for testing, use &lt;code&gt;dgit sbuild&lt;/code&gt; as &lt;a href="#uploading-a-new-package-to-debian"&gt;described below for uploading to NEW&lt;/a&gt;.
&lt;h2&gt;&lt;a name="uploading-to-debian"&gt;Uploading to Debian&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Start an MR branch for the administrative changes for the release.
&lt;p&gt;Document all the changes you&amp;rsquo;re going to release, in the &lt;code&gt;debian/changelog&lt;/code&gt;.
&lt;div style="background-color: #ddf; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git merge&lt;/h5&gt;

&lt;p&gt;gbp dch can help write the changelog for you:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;dgit fetch sid
gbp dch --ignore-branch --since=dgit/dgit/sid --git-log=^upstream/main&lt;/code&gt;&lt;/pre&gt;&lt;blockquote style="background-color: #cce; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;&lt;code&gt;--ignore-branch&lt;/code&gt; is needed because gbp dch wrongly thinks you ought to be running this on &lt;code&gt;master&lt;/code&gt;, but of course you&amp;rsquo;re running it on your MR branch.
&lt;p&gt;The &lt;code&gt;--git-log=^upstream/main&lt;/code&gt; excludes all upstream commits from the listing used to generate the changelog. (I&amp;rsquo;m assuming you have an &lt;code&gt;upstream&lt;/code&gt; remote and that you&amp;rsquo;re basing your work on their &lt;code&gt;main&lt;/code&gt; branch.) If there was a new upstream version, you&amp;rsquo;ll usually want to write a single line about that, and perhaps summarise anything really important.
&lt;/p&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;(For the first upload after switching to using tag2upload or dgit you need &lt;code&gt;--since=debian/1.2.3-1&lt;/code&gt;, where &lt;code&gt;1.2.3-1&lt;/code&gt; is your previous DEP-14 tag, because &lt;code&gt;dgit/dgit/sid&lt;/code&gt; will be a dsc import, not your actual history.)
&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;Change &lt;code&gt;UNRELEASED&lt;/code&gt; to the target suite, and finalise the changelog. (Note that &lt;code&gt;dch&lt;/code&gt; will insist that you at least save the file in your editor.)
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;dch -r
git commit -m &amp;#39;Finalise for upload&amp;#39; debian/changelog&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Make an MR of these administrative changes, and merge it. (Either set it to auto-merge and wait for CI, or if you&amp;rsquo;re in a hurry double-check that it really is just a changelog update so that you can be confident about telling Salsa to &amp;ldquo;Merge unverified changes&amp;rdquo;.)
&lt;p&gt;Now you can perform the actual upload:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git checkout master
git pull --ff-only # bring the gitlab-made MR merge commit into your local tree&lt;/code&gt;&lt;/pre&gt;&lt;div style="background-color: #ddf; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git merge&lt;/h5&gt;

&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git-debpush&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git-debpush --quilt=linear&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;--quilt=linear&lt;/code&gt; is needed only the first time, but it is very important that first time, to tell the system the correct git branch layout.
&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;h2&gt;&lt;a name="uploading-a-new-package-to-debian"&gt;Uploading a NEW package to Debian&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If your package is NEW (completely new source, or has new binary packages) you can&amp;rsquo;t do a source-only upload. You have to build the source and binary packages locally, and upload those build artifacts.
&lt;p&gt;Happily, given the same git branch you&amp;rsquo;d tag for tag2upload, and assuming you have sbuild installed and a suitable chroot, &lt;code&gt;dgit&lt;/code&gt; can help take care of the build and upload for you:
&lt;p&gt;Prepare the changelog update and merge it, as above. Then:
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;Create the orig tarball and launder the git-derebase branch:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git-deborig
git-debrebase quick&lt;/code&gt;&lt;/pre&gt;&lt;blockquote style="background-color: #ee9; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Source package format 3.0 (quilt), which is what I&amp;rsquo;m recommending here for use with git-debrebase, needs an orig tarball; it would also be needed for 1.0-with-diff.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;Build the source and binary packages, locally:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;dgit sbuild
dgit push-built&lt;/code&gt;&lt;/pre&gt;&lt;blockquote style="background-color: #eee; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;You don&amp;rsquo;t &lt;em&gt;have to&lt;/em&gt; use &lt;code&gt;dgit sbuild&lt;/code&gt;, but it is usually convenient to do so, because unlike sbuild, dgit understands git. Also it works around a &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=908747"&gt;gitignore-related defect&lt;/a&gt; in dpkg-source.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;&lt;a name="new-upstream-version"&gt;New upstream version&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Find the new upstream version number and corresponding tag. (Let&amp;rsquo;s suppose it&amp;rsquo;s &lt;code&gt;1.2.4&lt;/code&gt;.) Check the provenance:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git verify-tag v1.2.4&lt;/code&gt;&lt;/pre&gt;&lt;blockquote style="background-color: #eee; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Not all upstreams sign their git tags, sadly. Sometimes encouraging them to do so can help. You may need to use some other method(s) to check that you have the right git commit for the release.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;div style="background-color: #ddf; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git merge&lt;/h5&gt;

&lt;p&gt;Simply merge the new upstream version and update the changelog:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git merge v1.2.4
dch -v1.2.4-1 &amp;#39;New upstream release.&amp;#39;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;Rebase your delta queue onto the new upstream version:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git debrebase mew-upstream 1.2.4&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;If there are conflicts between your Debian delta for 1.2.3, and the upstream changes in 1.2.4, this is when you need to resolve them, as part of &lt;code&gt;git merge&lt;/code&gt; or &lt;code&gt;git (deb)rebase&lt;/code&gt;.
&lt;p&gt;After you&amp;rsquo;ve completed the merge, test your package and make any further needed changes. When you have it working in a local branch, make a Merge Request, as above.
&lt;h2&gt;&lt;a name="sponsorship"&gt;Sponsorship&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;git-based sponsorship is super easy! The sponsee can maintain their git branch on Salsa, and do all normal maintenance via gitlab operations.
&lt;p&gt;When the time comes to upload, the sponsee notifies the sponsor that it&amp;rsquo;s time. The sponsor fetches and checks out the git branch from Salsa, does their checks, as they judge appropriate, and when satisfied runs &lt;code&gt;git-debpush&lt;/code&gt;.
&lt;p&gt;As part of the sponsor&amp;rsquo;s checks, they might want to see all changes since the last upload to Debian:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;dgit fetch sid
git diff dgit/dgit/sid..HEAD&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or to see the Debian delta of the proposed upload:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git verify-tag v1.2.3
git diff v1.2.3..HEAD &amp;#39;:!debian&amp;#39;&lt;/code&gt;&lt;/pre&gt;&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;Or to show all the delta as a series of commits:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git log -p v1.2.3..HEAD &amp;#39;:!debian&amp;#39;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Don&amp;rsquo;t look at &lt;code&gt;debian/patches/&lt;/code&gt;. It can be absent or out of date.
&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;h2&gt;&lt;a name="incorporating-an-nmu"&gt;Incorporating an NMU&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Fetch the NMU into your local git, and see what it contains:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;dgit fetch sid
git diff master...dgit/dgit/sid&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the NMUer &lt;a href="https://manpages.debian.org/testing/dgit/dgit-nmu-simple.7.en.html"&gt;used dgit&lt;/a&gt;, then &lt;code&gt;git log dgit/dgit/sid&lt;/code&gt; will show you the commits they made.
&lt;p&gt;Normally the best thing to do is to simply merge the NMU, and then do any reverts or rework in followup commits:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git merge dgit/dgit/sid&lt;/code&gt;&lt;/pre&gt;&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;You should &lt;code&gt;git-debrebase quick&lt;/code&gt; at this stage, to check that the merge went OK and the package still has a lineariseable delta queue.
&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;p&gt;Then make any followup changes that seem appropriate. Supposing your previous maintainer upload was &lt;code&gt;1.2.3-7&lt;/code&gt;, you can go back and see the NMU diff again with:
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git diff debian/1.2.3-7...dgit/dgit/sid&lt;/code&gt;&lt;/pre&gt;&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;p&gt;The actual changes made to upstream files will always show up as diff hunks to those files. diff commands will often also show you changes to &lt;code&gt;debian/patches/&lt;/code&gt;. Normally it&amp;rsquo;s best to filter them out with &lt;code&gt;git diff ... &amp;#39;:!debian/patches&amp;#39;&lt;/code&gt;
&lt;p&gt;If you&amp;rsquo;d prefer to read the changes to the delta queue as an interdiff (diff of diffs), you can do something like
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git checkout debian/1.2.3-7
git-debrebase --force make-patches
git diff HEAD...dgit/dgit/sid -- :debian/patches&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to diff against a version with &lt;code&gt;debian/patches/&lt;/code&gt; up to date. (The NMU, in &lt;code&gt;dgit/dgit/sid&lt;/code&gt;, will necessarily have the patches already up to date.)
&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;

&lt;h2&gt;&lt;a name="dfsg-filtering-handling-non-free-files"&gt;DFSG filtering (handling non-free files)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some upstreams ship non-free files of one kind of another. Often these are just in the tarballs, in which case basing your work on upstream git avoids the problem. But if the files are in upstream&amp;rsquo;s git trees, you need to filter them out.
&lt;p&gt;&lt;strong&gt;This advice is not for (legally or otherwise) dangerous files&lt;/strong&gt;. If your package contains files that may be illegal, or hazardous, you need much more serious measures. In this case, even pushing the upstream git history to any Debian service, including Salsa, must be avoided. If you suspect this situation you should seek advice, privately and as soon as possible, from dgit-owner@d.o and/or the DFSG team. Thankfully, legally dangerous files are very rare in upstream git repositories, for obvious reasons.
&lt;p&gt;Our approach is to make a filtered git branch, based on the upstream history, with the troublesome files removed. We then treat that as the upstream for all of the rest of our work.
&lt;blockquote style="background-color: #eee; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Yes, this will end up including the non-free files in the git history, on official Debian servers. That&amp;rsquo;s OK. What&amp;rsquo;s forbidden is non-free material in the Debianised git tree, or in the source packages.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;h3&gt;&lt;a name="initial-filtering"&gt;Initial filtering&lt;/a&gt;&lt;/h3&gt;
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git checkout -b upstream-dfsg v1.2.3
git rm nonfree.exe
git commit -m &amp;quot;upstream version 1.2.3 DFSG-cleaned&amp;quot;
git tag -s -m &amp;quot;upstream version 1.2.3 DFSG-cleaned&amp;quot; v1.2.3+ds1
git push origin upstream-dfsg&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And now, use &lt;code&gt;1.2.3+ds1&lt;/code&gt;, and the filtered branch &lt;code&gt;upstream-dfsg&lt;/code&gt;, as the upstream version, instead of &lt;code&gt;1.2.3&lt;/code&gt; and &lt;code&gt;upstream/main&lt;/code&gt;. Follow the steps for &lt;a href="#convert-the-git-branch"&gt;Convert the git branch&lt;/a&gt; or &lt;a href="#new-upstream-version"&gt;New upstream version&lt;/a&gt;, as applicable, adding &lt;code&gt;+ds1&lt;/code&gt; into &lt;code&gt;debian/changelog&lt;/code&gt;.
&lt;p&gt;If you missed something and need to filter out more a nonfree files, re-use the same &lt;code&gt;upstream-dfsg&lt;/code&gt; branch and bump the &lt;code&gt;ds&lt;/code&gt; version, eg &lt;code&gt;v1.2.3+ds2&lt;/code&gt;.
&lt;h3&gt;&lt;a name="subsequent-upstream-releases"&gt;Subsequent upstream releases&lt;/a&gt;&lt;/h3&gt;
&lt;pre style="margin-left: 1em;"&gt;&lt;code&gt;git checkout upstream-dfsg
git merge v1.2.4
git rm additional-nonfree.exe # if any
git commit -m &amp;quot;upstream version 1.2.4 DFSG-cleaned&amp;quot;
git tag -s -m &amp;quot;upstream version 1.2.4 DFSG-cleaned&amp;quot; v1.2.4+ds1
git push origin upstream-dfsg&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;&lt;a name="removing-files-by-pattern"&gt;Removing files by pattern&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If the files you need to remove keep changing, you could automate things with a small shell script &lt;code&gt;debian/rm-nonfree&lt;/code&gt; containing appropriate &lt;code&gt;git rm&lt;/code&gt; commands. If you use &lt;code&gt;git rm -f&lt;/code&gt; it will succeed even if the &lt;code&gt;git merge&lt;/code&gt; from real upstream has conflicts due to changes to non-free files.
&lt;blockquote style="background-color: #eee; color: #222; font-style: italic;"&gt;
&lt;h6 style="margin-bottom: 0;"&gt;rationale&lt;/h6&gt;

&lt;p&gt;Ideally &lt;code&gt;uscan&lt;/code&gt;, which has a way of representing DFSG filtering patterns in &lt;code&gt;debian/watch&lt;/code&gt;, would be able to do this, but sadly the relevant functionality is entangled with uscan&amp;rsquo;s tarball generation.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;h1&gt;&lt;a name="common-issues"&gt;Common issues&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tarball contents&lt;/strong&gt;: If you are switching from upstream tarballs to upstream git, you may find that the git tree is significantly different.
&lt;p&gt;It may be missing files that your current build system relies on. If so, you definitely want to be using git, not the tarball. Those extra files in the tarball are intermediate built products, but in Debian we should be building from the real source! Fixing this may involve some work, though.

&lt;li&gt;&lt;p&gt;&lt;strong&gt;gitattributes&lt;/strong&gt;:
&lt;p&gt;For &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1079434#20"&gt;Reasons&lt;/a&gt; the dgit and tag2upload system disregards and disables the use of &lt;code&gt;.gitattributes&lt;/code&gt; to modify files as they are checked out.
&lt;p&gt;Normally this doesn&amp;rsquo;t cause a problem so long as any orig tarballs are generated the same way (as they will be by tag2upload or &lt;code&gt;git-deborig&lt;/code&gt;). But if the package or build system relies on them, you may need to institute some workarounds, or, replicate the effect of the gitattributes as commits in git.

&lt;li&gt;&lt;p&gt;&lt;strong&gt;git submodules&lt;/strong&gt;: &lt;a href="https://diziet.dreamwidth.org/14666.html"&gt;git submodules are terrible&lt;/a&gt; and should never ever be used. But not everyone has got the message, so your upstream may be using them.
&lt;p&gt;If you&amp;rsquo;re lucky, the code in the submodule isn&amp;rsquo;t used in which case you can &lt;code&gt;git rm&lt;/code&gt; the submodule.

&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h1&gt;&lt;a name="further-reading"&gt;Further reading&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I&amp;rsquo;ve tried to cover the most common situations. But software is complicated and there are many exceptions that this article can&amp;rsquo;t cover without becoming much harder to read.
&lt;p&gt;You may want to look at:
&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;dgit workflow manpages&lt;/strong&gt;: As part of the git transition project, we have written workflow manpages, which are more comprehensive than this article. They&amp;rsquo;re centered around use of dgit, but also discuss tag2upload where applicable.
&lt;p&gt;These cover a much wider range of possibilities, including (for example) choosing different source package formats, how to handle upstreams that publish only tarballs, etc. They are correspondingly much less opinionated.
&lt;p&gt;Look in &lt;a href="https://manpages.debian.org/testing/dgit/dgit-maint-merge.7.en.html"&gt;dgit-maint-merge(7)&lt;/a&gt; and &lt;a href="https://manpages.debian.org/testing/dgit/dgit-maint-debrebase.7.en.html"&gt;dgit-maint-debrebase(7)&lt;/a&gt;. There is also &lt;a href="https://manpages.debian.org/testing/dgit/dgit-maint-gbp.7.en.html"&gt;dgit-maint-gbp(7)&lt;/a&gt; for those who want to keep using &lt;code&gt;gbp pq&lt;/code&gt; and/or &lt;code&gt;quilt&lt;/code&gt; with a patches-unapplied branch.

&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;NMUs&lt;/strong&gt; are very easy with dgit. (tag2upload is usually less suitable than dgit, for an NMU.)
&lt;p&gt;You can work with any package, in git, in a completely uniform way, regardless of maintainer git workflow, See &lt;a href="https://manpages.debian.org/testing/dgit/dgit-nmu-simple.7.en.html"&gt;dgit-nmu-simple(7)&lt;/a&gt;.

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native packages&lt;/strong&gt; (meaning packages maintained wholly within Debian) are much simpler. See &lt;a href="https://manpages.debian.org/testing/dgit/dgit-maint-native.7.en.html"&gt;dgit-maint-native(7)&lt;/a&gt;.

&lt;li&gt;&lt;p&gt;&lt;strong&gt;tag2upload documentation&lt;/strong&gt;: The &lt;a href="https://wiki.debian.org/tag2upload"&gt;tag2upload wiki page&lt;/a&gt; is a good starting point. There&amp;rsquo;s the &lt;a href="https://manpages.debian.org/testing/git-debpush/git-debpush.1.en.html"&gt;git-debpush(1)&lt;/a&gt; manpage of course.

&lt;li&gt;&lt;p&gt;&lt;strong&gt;dgit reference documentation&lt;/strong&gt;:
&lt;p&gt;There is a comprehensive command-line manual in &lt;a href="https://manpages.debian.org/testing/dgit/dgit.1.en.html"&gt;dgit(1)&lt;/a&gt;. Description of the dgit data model and Principles of Operation is in &lt;a href="https://manpages.debian.org/testing/dgit/dgit.7.en.html"&gt;dgit(7)&lt;/a&gt;; including coverage of out-of-course situations.
&lt;p&gt;dgit is a complex and powerful program so this reference material can be overwhelming. So, we recommend starting with a guide like this one, or the dgit-&amp;hellip;(7) workflow tutorials.

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design and implementation documentation for tag2upload&lt;/strong&gt; is &lt;a href="https://wiki.debian.org/tag2upload#Signatures_and_traceability"&gt;linked to from the wiki&lt;/a&gt;.

&lt;li&gt;&lt;p&gt;&lt;a href="https://diziet.dreamwidth.org/20436.html"&gt;&lt;strong&gt;Debian&amp;rsquo;s git transition&lt;/strong&gt;&lt;/a&gt; blog post from December.
&lt;p&gt;tag2upload and dgit are part of the git transition project, and aim to support a very wide variety of git workflows. tag2upload and dgit work well with existing git tooling, including git-buildpackage-based approaches.
&lt;p&gt;git-debrebase is conceptually separate from, and functionally independent of, tag2upload and dgit. It&amp;rsquo;s a git workflow and delta management tool, competing with &lt;code&gt;gbp pq&lt;/code&gt;, manual use of &lt;code&gt;quilt&lt;/code&gt;, &lt;code&gt;git-dpm&lt;/code&gt; and so on.

&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;div style="background-color: #ffa; color: #000"&gt;
&lt;h5 style="margin-bottom: 0;"&gt;git-debrebase&lt;/h5&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;git-debrebase reference documentation&lt;/strong&gt;:
&lt;p&gt;Of course there&amp;rsquo;s a comprehensive command-line manual in &lt;a href="https://manpages.debian.org/testing/git-debrebase/git-debrebase.1.en.html"&gt;git-debrebase(1)&lt;/a&gt;.
&lt;p&gt;git-debrebase is quick and easy to use, but it has a complex data model and sophisticated algorithms. This is documented in &lt;a href="https://manpages.debian.org/testing/git-debrebase/git-debrebase.5.en.html"&gt;git-debrebase(5)&lt;/a&gt;.

&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;


&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;address&gt;
Edited 2026-03-05 18:48 UTC to add a missing &lt;code&gt;--noop-ok&lt;/code&gt; to the Salsa CI runes.  Thanks to Charlemagne Lasse for &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1129577"&gt;the report&lt;/a&gt;.  Apologies if this causes Debian Planet to re-post this article as if it were new.
&lt;/address&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=20851" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:20436</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/20436.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=20436"/>
    <title>Debian’s git transition</title>
    <published>2025-12-21T23:08:31Z</published>
    <updated>2025-12-21T23:24:29Z</updated>
    <category term="dgit"/>
    <category term="tag2upload"/>
    <category term="git"/>
    <category term="debian"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;p&gt;tl;dr:
&lt;p&gt;There is a Debian git transition plan. It&amp;rsquo;s going OK so far but we need help, especially with outreach and updating Debian&amp;rsquo;s documentation.
&lt;ul&gt;&lt;li&gt;&lt;a href="#goals-of-the-debian-git-transition-project"&gt;Goals of the Debian git transition project&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#achievements-so-far-and-current-status"&gt;Achievements so far, and current status&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#core-engineering-principle"&gt;Core engineering principle&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#correspondence-between-dsc-and-git"&gt;Correspondence between dsc and git&lt;/a&gt;
&lt;li&gt;&lt;a href="#patches-applied-vs-patches-unapplied"&gt;Patches-applied vs patches-unapplied&lt;/a&gt;
&lt;li&gt;&lt;a href="#consequences-some-of-which-are-annoying"&gt;Consequences, some of which are annoying&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#distributing-the-source-code-as-git"&gt;Distributing the source code as git&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#tracking-the-relevant-git-data-when-changes-are-made-in-the-legacy-archive"&gt;Tracking the relevant git data, when changes are made in the legacy Archive&lt;/a&gt;
&lt;li&gt;&lt;a href="#why-.dgit.debian.org-is-not-salsa"&gt;Why *.dgit.debian.org is not Salsa&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#roadmap"&gt;Roadmap&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#in-progress"&gt;In progress&lt;/a&gt;
&lt;li&gt;&lt;a href="#future-technology"&gt;Future Technology&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#mindshare-and-adoption---please-help"&gt;Mindshare and adoption - please help!&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#a-rant-about-publishing-the-source-code"&gt;A rant about publishing the source code&lt;/a&gt;
&lt;li&gt;&lt;a href="#documentation"&gt;Documentation&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#personnel"&gt;Personnel&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#thanks"&gt;Thanks&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h1&gt;&lt;a name="goals-of-the-debian-git-transition-project"&gt;Goals of the Debian git transition project&lt;/a&gt;&lt;/h1&gt;
&lt;ol start="0" type="1"&gt;&lt;li&gt;&lt;strong&gt;Everyone who interacts with Debian source code should be able to do so entirely in git.&lt;/strong&gt;
&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;That means, more specifically:
&lt;ol type="1"&gt;&lt;li&gt;&lt;p&gt;All examination and edits to the source should be performed via normal git operations.

&lt;li&gt;&lt;p&gt;Source code should be transferred and exchanged as git data, not tarballs. git should be the canonical form everywhere.

&lt;li&gt;&lt;p&gt;Upstream git histories should be re-published, traceably, as part of formal git releases published by Debian.

&lt;li&gt;&lt;p&gt;No-one should have to learn about Debian Source Packages, which are bizarre, and have been obsoleted by modern version control.

&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;This is very ambitious, but we have come a long way!
&lt;h2&gt;&lt;a name="achievements-so-far-and-current-status"&gt;Achievements so far, and current status&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We have come a very long way. But, there is still much to do - especially, the git transition team &lt;strong&gt;needs your help with adoption, developer outreach, and developer documentation overhaul.&lt;/strong&gt;
&lt;p&gt;We&amp;rsquo;ve made big strides towards goals 1 and 4. Goal 2 is partially achieved: we currently have dual running. Goal 3 is within our reach but depends on widespread adoption of tag2upload (and/or dgit push).
&lt;p&gt;Downstreams and users can &lt;a href="https://diziet.dreamwidth.org/17579.html"&gt;obtain the source code of any Debian package&lt;/a&gt; in git form. (&lt;a href="https://manpages.debian.org/trixie/dgit/dgit.1.en.html#dgit"&gt;dgit clone&lt;/a&gt;, 2013). They can then work with this source code completely in git, including building binaries, merging new versions, even automatically (eg &lt;a href="https://github.com/plugwash/autoforwardportergit?tab=readme-ov-file#pooltogit"&gt;Raspbian&lt;/a&gt;, 2016), and all without having to deal with source packages at all (eg &lt;a href="https://debconf25.debconf.org/talks/119-automating-downstream-debian-package-builds-and-updates-in-ci/"&gt;Wikimedia&lt;/a&gt; 2025).
&lt;p&gt;A Debian maintainer can maintain their own package entirely in git. They can obtain upstream source code from git, and do their packaging work in git (&lt;code&gt;git-buildpackage&lt;/code&gt;, 2006).
&lt;p&gt;Every Debian maintainer can (and should!) release their package &lt;em&gt;from git&lt;/em&gt; reliably and in a standard form (&lt;a href="https://manpages.debian.org/trixie/dgit/dgit.1.en.html#dgit~15"&gt;dgit push&lt;/a&gt;, 2013; &lt;a href="https://wiki.debian.org/tag2upload"&gt;tag2upload&lt;/a&gt;, 2025). This is not only more principled, but also more convenient, and with better UX, than pre-dgit tooling like &lt;code&gt;dput&lt;/code&gt;.
&lt;p&gt;Indeed a Debian maintainer can now often release their changes to Debian, from git, using &lt;em&gt;only&lt;/em&gt; git branches (so no tarballs). Releasing to Debian can be simply pushing a signed tag (&lt;a href="https://wiki.debian.org/tag2upload"&gt;tag2upload&lt;/a&gt;, 2025).
&lt;p&gt;A Debian maintainer can maintain a stack of changes to upstream source code in git (&lt;a href="https://manpages.debian.org/trixie/git-buildpackage/gbp-pq.1.en.html"&gt;gbp pq&lt;/a&gt; 2009). They can even maintain such a delta series as a rebasing git branch, directly buildable, and use normal &lt;code&gt;git rebase&lt;/code&gt; style operations to edit their changes, (&lt;a href="https://manpages.debian.org/trixie/git-dpm/git-dpm.1.en.html"&gt;git-dpm&lt;/a&gt;, 2010; &lt;a href="https://manpages.debian.org/trixie/git-debrebase/git-debrebase.1.en.html"&gt;git-debrebase&lt;/a&gt;, 2018)
&lt;p&gt;An authorised Debian developer can do a modest update to &lt;em&gt;any&lt;/em&gt; package in Debian, even one maintained by someone else, working entirely in git in a &lt;a href="https://manpages.debian.org/testing/dgit/dgit-nmu-simple.7.en.html"&gt;standard and convenient way&lt;/a&gt; (dgit, 2013).
&lt;p&gt;Debian contributors can share their work-in-progress on git forges and collaborate using merge requests, git based code review, and so on. (Alioth, 2003; Salsa, 2018.)
&lt;h1&gt;&lt;a name="core-engineering-principle"&gt;Core engineering principle&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The Debian git transition project is based on one core engineering principle:
&lt;p&gt;&lt;strong&gt;Every Debian Source Package can be losslessly converted to and from git.&lt;/strong&gt;
&lt;p&gt;In order to &lt;em&gt;transition&lt;/em&gt; away from Debian Source Packages, we need to &lt;em&gt;gateway&lt;/em&gt; between the old &lt;code&gt;dsc&lt;/code&gt; approach, and the new git approach.
&lt;p&gt;This gateway obviously needs to be bidirectional: source packages uploaded with legacy tooling like &lt;code&gt;dput&lt;/code&gt; need to be imported into a canonical git representation; and of course git branches prepared by developers need to be converted to source packages for the benefit of legacy downstream systems (such as the Debian Archive and &lt;code&gt;apt source&lt;/code&gt;).
&lt;p&gt;This bidirectional gateway is implemented in &lt;a href="https://salsa.debian.org/dgit-team/dgit"&gt;&lt;code&gt;src:dgit&lt;/code&gt;&lt;/a&gt;, and is allowing us to gradually replace dsc-based parts of the Debian system with git-based ones.
&lt;h2&gt;&lt;a name="correspondence-between-dsc-and-git"&gt;Correspondence between dsc and git&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A faithful bidirectional gateway must define an invariant:
&lt;p&gt;&lt;strong&gt;The canonical git tree, corresponding to a .dsc, is the tree resulting from &lt;code&gt;dpkg-source -x&lt;/code&gt;&lt;/strong&gt;.
&lt;p&gt;This canonical form is sometimes called the &amp;ldquo;dgit view&amp;rdquo;. It&amp;rsquo;s sometimes not the same as the maintainer&amp;rsquo;s git branch, because many maintainers are still working with &amp;ldquo;patches-unapplied&amp;rdquo; git branches. More on this below.
&lt;p&gt;(For &lt;code&gt;3.0 (quilt)&lt;/code&gt; .dscs, the canonical git tree doesn&amp;rsquo;t include the quilt &lt;code&gt;.pc&lt;/code&gt; directory.)
&lt;h2&gt;&lt;a name="patches-applied-vs-patches-unapplied"&gt;Patches-applied vs patches-unapplied&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The canonical git format is &amp;ldquo;patches applied&amp;rdquo;. That is:
&lt;p&gt;&lt;strong&gt;If Debian has modified the upstream source code, a normal git clone of the canonical branch gives the modified source tree, ready for reading and building.&lt;/strong&gt;
&lt;p&gt;Many Debian maintainers keep their packages in a different git branch format, where the changes made by Debian, to the upstream source code, are in actual &lt;code&gt;patch&lt;/code&gt; files in a &lt;code&gt;debian/patches/&lt;/code&gt; subdirectory.
&lt;p&gt;Patches-applied has a number of important advantages over patches-unapplied:
&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;It is familiar to, and doesn&amp;rsquo;t trick, outsiders to Debian&lt;/strong&gt;. Debian insiders radically underestimate how weird &amp;ldquo;patches-unapplied&amp;rdquo; is. Even expert software developers can get very confused or even &lt;a href="https://diziet.dreamwidth.org/9556.html"&gt;accidentally build binaries without security patches&lt;/a&gt;!

&lt;li&gt;&lt;p&gt;Making changes can be done with just normal git commands, eg &lt;code&gt;git commit&lt;/code&gt;. Many Debian insiders working with patches-unapplied are still using &lt;a href="https://manpages.debian.org/trixie/quilt/quilt.1.en.html"&gt;&lt;code&gt;quilt(1)&lt;/code&gt;&lt;/a&gt;, a footgun-rich contraption for working with patch files!

&lt;li&gt;&lt;p&gt;When developing, one can make changes to upstream code, and to Debian packaging, together, without ceremony. There is no need to switch back and forth between patch queue and packaging branches (as with &lt;code&gt;gbp pq&lt;/code&gt;), no need to &amp;ldquo;commit&amp;rdquo; patch files, etc. One can always edit every file and commit it with &lt;code&gt;git commit&lt;/code&gt;.

&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The downside is that, with the (bizarre) &lt;code&gt;3.0 (quilt)&lt;/code&gt; source format, the patch files files in &lt;code&gt;debian/patches/&lt;/code&gt; must somehow be kept up to date. Nowadays though, tools like &lt;code&gt;git-debrebase&lt;/code&gt; and &lt;code&gt;git-dpm&lt;/code&gt; (and dgit for NMUs) make it very easy to work with patches-applied git branches. &lt;code&gt;git-debrebase&lt;/code&gt; can deal very ergonomically even with &lt;a href="https://salsa.debian.org/xen-team/debian-xen"&gt;big patch stacks&lt;/a&gt;.
&lt;p&gt;(For smaller packages which usually have no patches, &lt;a href="https://manpages.debian.org/trixie/dgit/dgit-maint-merge.7.en.html"&gt;plain &lt;code&gt;git merge&lt;/code&gt; with an upstream git branch&lt;/a&gt;, and a &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1007717#384"&gt;much simpler dsc format&lt;/a&gt;, sidesteps the problem entirely.)
&lt;h3&gt;&lt;a name="prioritising-debians-users-and-other-outsiders"&gt;Prioritising Debian&amp;rsquo;s users (and other outsiders)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We want everyone to be able to share and modify the software that they interact with. That means we should make source code truly accessible, on the user&amp;rsquo;s terms.
&lt;p&gt;Many of Debian&amp;rsquo;s processes assume everyone is an insider. It&amp;rsquo;s okay that there are Debian insiders and that people feel part of something that they worked hard to become involved with. But lack of perspective can lead to software which fails to uphold our values.
&lt;p&gt;Our source code practices &amp;mdash; in particular, our determination to share properly (and systematically) &amp;mdash; are a key part of what makes Debian worthwhile at all. Like Debian&amp;rsquo;s installer, we want our source code to be useable by Debian outsiders.
&lt;p&gt;This is why we have chosen to privilege a git branch format which is more familiar to the world at large, even if it&amp;rsquo;s less popular in Debian.
&lt;h2&gt;&lt;a name="consequences-some-of-which-are-annoying"&gt;Consequences, some of which are annoying&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The requirement that the conversion be &lt;em&gt;bidirectional&lt;/em&gt;, &lt;em&gt;lossless&lt;/em&gt;, and &lt;em&gt;context-free&lt;/em&gt; can be inconvenient.
&lt;p&gt;For example, &lt;a href="https://manpages.debian.org/trixie/dgit/dgit.7.en.html#GITATTRIBUTES"&gt;we cannot support &lt;code&gt;.gitattributes&lt;/code&gt;&lt;/a&gt; which modify files during git checkin and checkout. &lt;code&gt;.gitattributes&lt;/code&gt; cause the meaning of a git tree to depend on the context, in possibly arbitrary ways, so the conversion from git to source package wouldn&amp;rsquo;t be stable. And, worse, some source packages might not to be representable in git at all.
&lt;p&gt;Another example: Maintainers often have existing git branches for their packages, generated with pre-dgit tooling which is less careful and less principled than ours. That can result in discrepancies between git and dsc, which need to be resolved before a proper git-based upload can succeed.
&lt;p&gt;That some maintainers use patches-unapplied, and some patches-unapplied, means that there &lt;em&gt;has&lt;/em&gt; to be some kind of conversion to a standard git representation. Choosing the less-popular patches-applied format as the canonical form, means that &lt;em&gt;many&lt;/em&gt; packages need their git representation converted. It also means that user- and outsider-facing branches from &lt;code&gt;{browse,git}.dgit.d.o&lt;/code&gt; and &lt;code&gt;dgit clone&lt;/code&gt; are not always compatible with maintainer branches on Salsa. User-contributed changes need cherry-picking rather than merging, or conversion back to the maintainer format. The good news is that dgit can automate much of this, and the manual parts are usually easy git operations.
&lt;h1&gt;&lt;a name="distributing-the-source-code-as-git"&gt;Distributing the source code as git&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Our source code management should be normal, modern, and based on git. That means the Debian Archive is obsolete and needs to be replaced with a set of git repositories.
&lt;p&gt;The replacement repository for source code formally released to Debian is &lt;a href="https://browse.dgit.debian.org/"&gt;&lt;code&gt;*.dgit.debian.org&lt;/code&gt;&lt;/a&gt;. This contains all the git objects for every git-based upload since 2013, including the signed tag for each released package version.
&lt;p&gt;The plan is that it will contain a git view of &lt;em&gt;every&lt;/em&gt; uploaded Debian package, by centrally importing all legacy uploads into git.
&lt;h2&gt;&lt;a name="tracking-the-relevant-git-data-when-changes-are-made-in-the-legacy-archive"&gt;Tracking the relevant git data, when changes are made in the legacy Archive&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Currently, many critical source code management tasks are done by changes to the legacy Debian Archive, which works entirely with dsc files (and the associated tarballs etc). The contents of the Archive are therefore still an important source of truth. But, the Archive&amp;rsquo;s architecture means it cannot sensibly directly contain git data.
&lt;p&gt;To track changes made in the Archive, we added the &lt;a href="https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-dgit"&gt;&lt;code&gt;Dgit:&lt;/code&gt;&lt;/a&gt; field to the &lt;code&gt;.dsc&lt;/code&gt; of a git-based upload (2013). This declares which git commit this package was converted from. and where those git objects can be obtained.
&lt;p&gt;Thus, given a Debian Source Package from a git-based upload, it is possible for the new git tooling to obtain the equivalent git objects. If the user is going to work in git, there is no need for any tarballs to be downloaded: the git data could be obtained from the depository using the git protocol.
&lt;p&gt;The &lt;a href="https://browse.dgit.debian.org/libsdl2-ttf.git/tag/?h=archive/debian/2.24.0%2bdfsg-3"&gt;signed&lt;/a&gt; &lt;a href="https://browse.dgit.debian.org/libsdl2-ttf.git/tag/?h=debian/2.24.0%2bdfsg-3"&gt;tags&lt;/a&gt;, available from the git depository, have &lt;a href="https://manpages.debian.org/trixie/git-debpush/tag2upload.5.en.html"&gt;standardised metdata&lt;/a&gt; which gives traceability back to the uploading Debian contributor.
&lt;h2&gt;&lt;a name="why-.dgit.debian.org-is-not-salsa"&gt;Why *.dgit.debian.org is not Salsa&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We need a git &lt;em&gt;depository&lt;/em&gt; - a formal, reliable and permanent git repository of source code actually released to Debian.
&lt;p&gt;Git forges like Gitlab can be very convenient. But Gitlab is not sufficiently secure, &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/429516"&gt;and&lt;/a&gt; &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/472646"&gt;too&lt;/a&gt; &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/581752"&gt;full&lt;/a&gt; &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/581897"&gt;of&lt;/a&gt; &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/217231"&gt;bugs&lt;/a&gt;, to be the principal and only archive of all our source code. (The &amp;ldquo;open core&amp;rdquo; business model of the Gitlab corporation, and the constant-churn development approach, are &lt;a href="https://mako.cc/writing/hill-free_tools.html"&gt;critical&lt;/a&gt; underlying problems.)
&lt;p&gt;Our git depository lacks forge features like Merge Requests. But:
&lt;ul&gt;&lt;li&gt;It is dependable, both in terms of reliability and security.
&lt;li&gt;It is append-only: once something is pushed, it is permanently recorded.
&lt;li&gt;Its access control is precisely that of the Debian Archive.
&lt;li&gt;Its ref namespace is standardised and corresponds to Debian releases.
&lt;li&gt;Pushes are authorised by PGP signatures, not ssh keys, so traceable.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The dgit git depository outlasted Alioth and it may well outlast Salsa.
&lt;p&gt;We need &lt;em&gt;both&lt;/em&gt; a good forge, and the &lt;code&gt;*.dgit.debian.org&lt;/code&gt; formal git depository.
&lt;h1&gt;&lt;a name="roadmap"&gt;Roadmap&lt;/a&gt;&lt;/h1&gt;
&lt;h2&gt;&lt;a name="in-progress"&gt;In progress&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Right now we are quite focused on &lt;a href="https://wiki.debian.org/tag2upload"&gt;&lt;strong&gt;tag2upload&lt;/strong&gt;&lt;/a&gt;.
&lt;p&gt;We are working hard on eliminating the remaining issues that we feel need to be addressed before declaring the service out of beta.
&lt;h2&gt;&lt;a name="future-technology"&gt;Future Technology&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;a name="whole-archive-dsc-importer"&gt;Whole-archive dsc importer&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Currently, the git depository only has git data for git-based package updates (tag2upload and dgit push). Legacy dput-based uploads are not currently present there. This means that the git-based and legacy uploads must be resolved client-side, by &lt;code&gt;dgit clone&lt;/code&gt;.
&lt;p&gt;We will want to start importing legacy uploads to git.
&lt;p&gt;Then downstreams and users will be able to get the source code for any package simply with &lt;code&gt;git clone&lt;/code&gt;, even if the maintainer is using legacy upload tools like dput.
&lt;h3&gt;&lt;a name="support-for-git-based-uploads-to-security.debian.org"&gt;Support for git-based uploads to security.debian.org&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Security patching is a task which would particularly benefit from better and more formal use of git. git-based approaches to applying and backporting security patches are much more convenient than messing about with actual patch files.
&lt;p&gt;Currently, one can use git to help prepare a security upload, but it often involves starting with a dsc import (which lacks the proper git history) or figuring out a package maintainer&amp;rsquo;s unstandardised git usage conventions on Salsa.
&lt;p&gt;And it is not possible to properly perform the security release &lt;em&gt;as git&lt;/em&gt;.
&lt;h3&gt;&lt;a name="internal-debian-consumers-switch-to-getting-source-from-git"&gt;Internal Debian consumers switch to getting source from git&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Buildds, QA work such as lintian checks, and so on, could be simpler if they don&amp;rsquo;t need to deal with source packages.
&lt;p&gt;And since git is actually the canonical form, we want them to use it directly.
&lt;h3&gt;&lt;a name="problems-for-the-distant-future"&gt;Problems for the distant future&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For decades, Debian has been built around source packages. Replacing them is a long and complex process. Certainly source packages are going to continue to be supported for the foreseeable future.
&lt;p&gt;There are no doubt going to be unanticipated problems. There are also foreseeable issues: for example, perhaps there are packages that work very badly when represented in git. We think we can rise to these challenges as they come up.
&lt;h1&gt;&lt;a name="mindshare-and-adoption---please-help"&gt;Mindshare and adoption - please help!&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;We and our users are very pleased with our technology. It is convenient and highly dependable.
&lt;p&gt;&lt;code&gt;dgit&lt;/code&gt; in particular is superb, even if we say so ourselves. As technologists, we have been very focused on building good software, but it seems we have fallen short in the marketing department.
&lt;h2&gt;&lt;a name="a-rant-about-publishing-the-source-code"&gt;A rant about publishing the source code&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;git is the preferred form for modification&lt;/strong&gt;.
&lt;p&gt;Our upstreams are overwhelmingly using git. We are overwhelmingly using git. It is a scandal that for many packages, Debian does not properly, formally and officially publish the git history.
&lt;p&gt;&lt;em&gt;Properly&lt;/em&gt; publishing the source code as git means publishing it in a way that means that anyone can &lt;em&gt;automatically&lt;/em&gt; and &lt;em&gt;reliably&lt;/em&gt; obtain &lt;em&gt;and build&lt;/em&gt; the &lt;em&gt;exact&lt;/em&gt; source code corresponding to the binaries. The test is: could you use that to build a derivative?
&lt;p&gt;Putting a package &lt;a href="https://dep-team.pages.debian.net/deps/dep18/"&gt;in git on Salsa&lt;/a&gt; is often a good idea, but it is not sufficient. No standard branch structure git on Salsa is enforced, nor should it be (so it can&amp;rsquo;t be automatically and reliably obtained), the tree is not in a standard form (so it can&amp;rsquo;t be automatically built), and is not &lt;em&gt;necessarily identical&lt;/em&gt; to the source package. So &lt;code&gt;Vcs-Git&lt;/code&gt; fields, and git from Salsa, will never be sufficient to make a derivative.
&lt;p&gt;&lt;strong&gt;Debian is not publishing the source code!&lt;/strong&gt;
&lt;p&gt;The time has come for proper publication of source code by Debian to no longer be a minority sport. Every maintainer of a package whose upstream is using git (which is nearly all packages nowadays) should be basing their work on upstream git, and properly publishing that via tag2upload or dgit.
&lt;p&gt;And it&amp;rsquo;s not even difficult! The modern git-based tooling provides a far superior upload experience.
&lt;h3&gt;&lt;a name="a-common-misunderstanding"&gt;A common misunderstanding&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;dgit push is not an alternative to gbp pq or quilt. Nor is tag2upload.&lt;/strong&gt; These upload tools &lt;em&gt;complement your existing git workflow&lt;/em&gt;. They replace and improve source package building/signing and the subsequent dput. If you are using one of the usual git layouts on salsa, and your package is in good shape, you can adopt tag2upload and/or dgit push right away.
&lt;p&gt;&lt;code&gt;git-debrebase&lt;/code&gt; is distinct and &lt;em&gt;does&lt;/em&gt; provides an alternative way to manage your git packaging, do your upstream rebases, etc.
&lt;h2&gt;&lt;a name="documentation"&gt;Documentation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Debian&amp;rsquo;s documentation all needs to be updated, including particularly instructions for packaging, to recommend use of git-first workflows. Debian should not be importing git-using upstreams&amp;rsquo; &amp;ldquo;release tarballs&amp;rdquo; into git. (Debian outsiders who discover this practice are typically horrified.) We should use &lt;em&gt;only&lt;/em&gt; upstream git, work only in git, and properly release (and publish) in git form.
&lt;p&gt;We, the git transition team, are experts in the technology, and can provide good suggestions. But we do not have the bandwidth to also engage in the massive campaigns of education and documentation updates that are necessary &amp;mdash; especially given that (as with any programme for change) many people will be sceptical or even hostile.
&lt;p&gt;So we would greatly appreciate help with writing and outreach.
&lt;h1&gt;&lt;a name="personnel"&gt;Personnel&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;We consider ourselves the Debian git transition team.
&lt;p&gt;Currently we are:
&lt;ul&gt;&lt;li&gt;&lt;p&gt;Ian Jackson. Author and maintainer of dgit and git-debrebase. Co-creator of tag2upload. Original author of dpkg-source, and inventor in 1996 of Debian Source Packages. Alumnus of the Debian Technical Committee.

&lt;li&gt;&lt;p&gt;Sean Whitton. Co-creator of the tag2upload system; author and maintainer of git-debpush. Co-maintainer of dgit. Debian Policy co-Editor. Former Chair of the Debian Technical Committee.

&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;We wear the following hats related to the git transition:
&lt;ul&gt;&lt;li&gt;Maintainers of src:dgit
&lt;li&gt;&lt;a href="https://lists.debian.org/debian-devel-announce/2025/01/msg00002.html"&gt;tag2upload Delegates&lt;/a&gt;; operators of the &lt;a href="https://tag2upload.debian.org/"&gt;tag2upload service&lt;/a&gt;.
&lt;li&gt;service operators of the git depository &lt;a href="https://browse.dgit.debian.org/"&gt;*.dgit.debian.org&lt;/a&gt;.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;You can contact us:
&lt;ul&gt;&lt;li&gt;&lt;p&gt;By email: Ian Jackson &lt;a class="email" href="mailto:ijackson@chiark.greenend.org.uk"&gt;ijackson@chiark.greenend.org.uk&lt;/a&gt;; Sean Whitton &lt;a class="email" href="mailto:spwhitton@spwhitton.name"&gt;spwhitton@spwhitton.name&lt;/a&gt;; git-debpush@packages.d.o.

&lt;li&gt;&lt;p&gt;By filing bugs in the Debian Bug System against &lt;a href="https://bugs.debian.org/src:dgit"&gt;src:dgit&lt;/a&gt;.

&lt;li&gt;&lt;p&gt;On OFTC IRC, as &lt;code&gt;Diziet&lt;/code&gt; and &lt;code&gt;spwhitton&lt;/code&gt;.

&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;We do most of our heavy-duty development &lt;a href="https://salsa.debian.org/dgit-team"&gt;on Salsa&lt;/a&gt;.
&lt;h2&gt;&lt;a name="thanks"&gt;Thanks&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Particular thanks are due to Joey Hess, who, in the now-famous design session in Vaumarcus in 2013, helped invent dgit. Since then we have had a lot of support: most recently political support to help get tag2upload deployed, but also, over the years, helpful bug reports and kind words from our users, as well as translations and code contributions.
&lt;p&gt;Many other people have contributed more generally to support for working with Debian source code in git. We particularly want to mention Guido G&amp;uuml;nther (git-buildpackage); and of course Alexander Wirt, Joerg Jaspert, Thomas Goirand and Antonio Terceiro (Salsa administrators); and before them the Alioth administrators.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=20436" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:20143</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/20143.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=20143"/>
    <title>tag2upload in the first month of forky</title>
    <published>2025-09-14T15:36:17Z</published>
    <updated>2025-09-14T15:36:41Z</updated>
    <category term="computers"/>
    <category term="dgit"/>
    <category term="tag2upload"/>
    <category term="git"/>
    <category term="debian"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;p&gt;tl;dr: &lt;a href="https://wiki.debian.org/tag2upload"&gt;tag2upload&lt;/a&gt; (beta) is going well so far, and is already handling around one in 13 uploads to Debian.
&lt;ul&gt;&lt;li&gt;&lt;a href="#introduction-and-some-stats"&gt;Introduction and some stats&lt;/a&gt;
&lt;li&gt;&lt;a href="#recent-uiux-improvements"&gt;Recent UI/UX improvements&lt;/a&gt;
&lt;li&gt;&lt;a href="#why-we-are-still-in-beta"&gt;Why we are still in beta&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#retrying-on-salsa-side-failures"&gt;Retrying on Salsa-side failures&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#other-notable-ongoing-work"&gt;Other notable ongoing work&lt;/a&gt;
&lt;li&gt;&lt;a href="#common-problems"&gt;Common problems&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#reuse-of-version-numbers-and-attempts-to-re-tag"&gt;Reuse of version numbers, and attempts to re-tag&lt;/a&gt;
&lt;li&gt;&lt;a href="#discrepancies-between-git-and-orig-tarballs"&gt;Discrepancies between git and orig tarballs&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#get-involved"&gt;Get involved&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h3&gt;&lt;a name="introduction-and-some-stats"&gt;Introduction and some stats&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We announced tag2upload&amp;rsquo;s open beta in mid-July. That was in the middle of the the freeze for trixie, so usage was fairly light until the forky floodgates opened.
&lt;p&gt;Since then the service has successfully performed &lt;strong&gt;637 uploads&lt;/strong&gt;, of which 420 were in the last 32 days. That&amp;rsquo;s an average of about 13 per day. For comparison, during the first half of September up to today there have been 2475 uploads to unstable. That&amp;rsquo;s about 176/day.
&lt;p&gt;So, tag2upload is already handling around 7.5% of uploads. This is very gratifying for a service which is advertised as still being in beta!
&lt;p&gt;Sean and I are very pleased both with the uptake, and with the way the system has been performing.
&lt;h3&gt;&lt;a name="recent-uiux-improvements"&gt;Recent UI/UX improvements&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;During this open beta period we have been hard at work. We have made many improvements to the user experience.
&lt;p&gt;Current &lt;code&gt;git-debpush&lt;/code&gt; in forky, or trixie-backports, is much better at detecting various problems ahead of time.
&lt;p&gt;When uploads do fail on the service the emailed error reports are now more informative. For example, anomalies involving orig tarballs, which by definition can&amp;rsquo;t be detected locally (since one point of tag2upload is not to have tarballs locally) now generally result in failure reports containing a diffstat, and instructions for a local repro.
&lt;h3&gt;&lt;a name="why-we-are-still-in-beta"&gt;Why we are still in beta&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There are a few outstanding work items that we currently want to complete before we declare the end of the beta.
&lt;h4&gt;&lt;a name="retrying-on-salsa-side-failures"&gt;Retrying on Salsa-side failures&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The biggest of these is that the service should be able to retry when Salsa fails. Sadly, Salsa isn&amp;rsquo;t wholly reliable, and right now if it breaks when the service is trying to handle your tag, your upload can fail.
&lt;p&gt;We think most of these failures could be avoided. Implementing retries is a fairly substantial task, but doesn&amp;rsquo;t pose any fundamental difficulties. We&amp;rsquo;re working on this right now.
&lt;h3&gt;&lt;a name="other-notable-ongoing-work"&gt;Other notable ongoing work&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We want to support pristine-tar, so that pristine-tar users can do a new upstream release. Andrea Pappacoda is working on that with us. See &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1106071"&gt;#1106071&lt;/a&gt;. (Note that we would generally &lt;strong&gt;recommend against use of pristine-tar&lt;/strong&gt; within Debian. But we want to support it.)
&lt;p&gt;We have been having conversations with &lt;a href="https://salsa.debian.org/freexian-team/debusine"&gt;Debusine&lt;/a&gt; folks about what integration between tag2upload and Debusine would look like. We&amp;rsquo;re &lt;a href="https://salsa.debian.org/freexian-team/debusine/-/issues/815#note_651533"&gt;making some progress&lt;/a&gt; there, but a lot is still up in the air.
&lt;p&gt;&lt;a href="https://salsa.debian.org/salsa-ci-team/pipeline/-/issues/467#note_642152"&gt;We are considering&lt;/a&gt; how best to provide tag2upload pre-checks as part of Salsa CI. There are several problems detected by the tag2upload service that could be detected by Salsa CI too, but which can&amp;rsquo;t be detected by &lt;code&gt;git-debpush&lt;/code&gt;.
&lt;h3&gt;&lt;a name="common-problems"&gt;Common problems&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;ve been monitoring the service and until very recently we have investigated every service-side failure, to understand the root causes. This has given us insight into the kinds of things our users want, and the kinds of packaging and git practices that are common. We&amp;rsquo;ve been able to improve the system&amp;rsquo;s handling of various anomalies and also improved the documentation.
&lt;p&gt;Right now our failure rate is still rather high, at around 7%. Partly this is because people are trying out the system on packages that haven&amp;rsquo;t ever seen git tooling with such a level of rigour.
&lt;p&gt;There are two classes of problem that are responsible for the vast majority of the failures that we&amp;rsquo;re still seeing:
&lt;h4&gt;&lt;a name="reuse-of-version-numbers-and-attempts-to-re-tag"&gt;Reuse of version numbers, and attempts to re-tag&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;tag2upload, like git (and like &lt;code&gt;dgit&lt;/code&gt;), hates it when you reuse a version number, or try to pretend that a (perhaps busted) release never happened.
&lt;p&gt;git tags aren&amp;rsquo;t namespaced, and tend to spread about promiscuously. So replacing a signed git tag, with a different tag of the same name, is a bad idea. More generally, reusing the same version number for a different (signed!) package is poor practice. Likewise, it&amp;rsquo;s usually a bad idea to remove changelog entries for versions which were actually released, just because they were later deemed improper.
&lt;p&gt;We understand that many Debian contributors have gotten used to this kind of thing. Indeed, tools like &lt;code&gt;dcut&lt;/code&gt; encourage it. It does allow you to make things neat-looking, even if you&amp;rsquo;ve made mistakes - but really it does so by &lt;em&gt;covering up&lt;/em&gt; those mistakes!
&lt;p&gt;The bottom line is that tag2upload can&amp;rsquo;t support such history-rewriting. If you discover a mistake after you&amp;rsquo;ve signed the tag, please just &lt;strong&gt;burn the version number and add a new changelog stanza&lt;/strong&gt;.
&lt;p&gt;One bonus of tag2upload&amp;rsquo;s approach is that it will discover if you are accidentally overwriting an NMU, and report that as an error.
&lt;h4&gt;&lt;a name="discrepancies-between-git-and-orig-tarballs"&gt;Discrepancies between git and orig tarballs&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;tag2upload promises that the source package that it generates corresponds precisely to the git tree you tag and sign.
&lt;p&gt;Orig tarballs make this complicated. They aren&amp;rsquo;t present on your laptop when you &lt;code&gt;git-debpush&lt;/code&gt;. When you&amp;rsquo;re not uploading a new upstream version, the tag2upload service reuses existing orig tarballs from the archive. If your git and the archive&amp;rsquo;s orig don&amp;rsquo;t agree, the tag2upload service will report an error, rather than upload a package with contents that differ from your git tag.
&lt;p&gt;With the most common Debian workflows, everything is fine:
&lt;p&gt;If you base everything on upstream git, and make your orig tarballs with &lt;code&gt;git archive&lt;/code&gt; (or &lt;code&gt;git deborig&lt;/code&gt;), your orig tarballs are the same as the git, by construction. &lt;strong&gt;We recommend usually ignoring upstream tarballs&lt;/strong&gt;: most upstreams work in git, and their tarballs can contain weirdness that we don&amp;rsquo;t want. (At worst, the tarball can contain an attack that isn&amp;rsquo;t visible in git, as with &lt;code&gt;xz&lt;/code&gt;!)
&lt;p&gt;Alternatively, if you use &lt;code&gt;gbp import-orig&lt;/code&gt;, the differences (including an attack like Jia Tan&amp;rsquo;s) are &lt;em&gt;imported into&lt;/em&gt; git for you. Then, once again, your git and the orig tarball will correspond.
&lt;p&gt;But there are other workflows where this correspondence may not hold. Those workflows are hazardous, because the thing you&amp;rsquo;re probably working with locally for your routine development is the git view. Then, when you upload, your work is transplanted onto the orig tarball, which might be quite different - so what you upload isn&amp;rsquo;t what you&amp;rsquo;ve been working on!
&lt;p&gt;This situation is detected by tag2upload, precisely because tag2upload checks that it&amp;rsquo;s keeping its promise: the source package is identical to the git view. (&lt;code&gt;dgit push&lt;/code&gt; makes the same promise.)
&lt;h3&gt;&lt;a name="get-involved"&gt;Get involved&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Of course the easiest way to get involved is to &lt;a href="https://wiki.debian.org/tag2upload"&gt;start using tag2upload&lt;/a&gt;.
&lt;p&gt;We would love to have more contributors. There are some easy tasks to get started with, in &lt;a href="https://bugs.debian.org/cgi-bin/pkgreport.cgi?src=dgit;tag=newcomer"&gt;bugs we&amp;rsquo;ve tagged &amp;ldquo;newcomer&amp;rdquo;&lt;/a&gt; &amp;mdash; mostly UX improvements such as detecting certain problems earlier, in &lt;code&gt;git-debpush&lt;/code&gt;.
&lt;p&gt;More substantially, we are looking for help with &lt;code&gt;sbuild&lt;/code&gt;: we&amp;rsquo;d like it to be able to work directly from git, rather than needing to build source packages: &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=868527"&gt;#868527&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=20143" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:19879</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/19879.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=19879"/>
    <title>Free Software, internal politics, and governance</title>
    <published>2025-05-01T22:03:17Z</published>
    <updated>2025-05-01T22:15:54Z</updated>
    <category term="computers"/>
    <category term="politics"/>
    <dw:security>public</dw:security>
    <dw:reply-count>2</dw:reply-count>
    <content type="html">&lt;p&gt;There is a thread of opinion in some Free Software communities, that we shouldn&amp;rsquo;t be doing &amp;ldquo;politics&amp;rdquo;, and instead should just focus on technology.
&lt;p&gt;But that&amp;rsquo;s impossible. This approach is naive, harmful, and, ultimately, self-defeating, even on its own narrow terms.
&lt;ul&gt;&lt;li&gt;&lt;a href="#today-im-talking-about-small-p-politics"&gt;Today I&amp;rsquo;m talking about small-p politics&lt;/a&gt;
&lt;li&gt;&lt;a href="#many-people-working-together-always-entails-politics"&gt;Many people working together always entails politics&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#consensus-is-great-but-always-requiring-it-is-harmful"&gt;Consensus is great but always requiring it is harmful&lt;/a&gt;
&lt;li&gt;&lt;a href="#governance-is-like-backups-we-need-to-practice-it"&gt;Governance is like backups: we need to practice it&lt;/a&gt;
&lt;li&gt;&lt;a href="#governance-should-usually-be-routine-and-boring"&gt;Governance should usually be routine and boring&lt;/a&gt;
&lt;li&gt;&lt;a href="#governance-means-deciding-not-just-mediating"&gt;Governance means deciding, not just mediating&lt;/a&gt;
&lt;li&gt;&lt;a href="#on-the-autonomy-of-the-programmer"&gt;On the autonomy of the programmer&lt;/a&gt;
&lt;li&gt;&lt;a href="#mitigate-the-consequences-of-decisions-retain-flexibility"&gt;Mitigate the consequences of decisions &amp;mdash; retain flexibility&lt;/a&gt;
&lt;li&gt;&lt;a href="#but-dont-do-decisionmaking-like-a-corporation"&gt;But don&amp;rsquo;t do decisionmaking like a corporation&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#if-you-wont-do-politics-politics-will-do-you"&gt;If you won&amp;rsquo;t do politics, politics will do you&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#if-you-dont-see-the-politics-its-still-happening"&gt;If you don&amp;rsquo;t see the politics, it&amp;rsquo;s still happening&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#conclusions"&gt;Conclusions&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h2&gt;&lt;a name="today-im-talking-about-small-p-politics"&gt;Today I&amp;rsquo;m talking about small-p politics&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this article I&amp;rsquo;m using &amp;ldquo;politics&amp;rdquo; in the very wide sense: us humans managing our disagreements with each other.
&lt;p&gt;I&amp;rsquo;m &lt;em&gt;not&lt;/em&gt; going to talk about culture wars, woke, racism, trans rights, and so on. I am &lt;em&gt;not&lt;/em&gt; going to talk about how Free Software has always had explicitly political goals; or how it&amp;rsquo;s impossible to be neutral because choosing not to take a stand is itself to take a stand.
&lt;p&gt;Those issues are all are important and Free Software definitely must engage with them. Many of the points I make are applicable there too. But those are not my focus today.
&lt;p&gt;Today I&amp;rsquo;m talking in more general terms about politics, power, and governance.
&lt;h2&gt;&lt;a name="many-people-working-together-always-entails-politics"&gt;Many people working together always entails politics&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Computers are incredibly complicated nowadays. Making software is a joint enterprise. Even if an individual program has only a single maintainer, it fits into an ecosystem of other software, maintained by countless other developers. Larger projects can have thousands of maintainers and hundreds of thousands of contributors.
&lt;p&gt;Humans don&amp;rsquo;t always agree about everything. This is natural. Indeed, it&amp;rsquo;s healthy: to write the best code, we need a wide range of knowledge and experience.
&lt;p&gt;When we can&amp;rsquo;t come to agreement, we need a way to deal with that: a way that lets us still make progress, but also leaves us able to work together afterwards. A way that feels OK for everyone.
&lt;p&gt;Providing a framework for disagreement is the job of a governance system. The rules say which people make which decisions, who must be consulted, how the decisions are made, and, how, if any, they can be reviewed.
&lt;p&gt;This is all politics.
&lt;h3&gt;&lt;a name="consensus-is-great-but-always-requiring-it-is-harmful"&gt;Consensus is great but always requiring it is harmful&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ideally a discussion will converge to a synthesis that satisfies everyone, or at least a consensus.
&lt;p&gt;When consensus can&amp;rsquo;t be achieved, we can hope for compromise: something everyone can live with. Compromise is achieved through negotiation.
&lt;p&gt;If every decision requires consensus, then the proponents of any wide-ranging improvement have an almost insurmountable hurdle: those who are favoured by the status quo and find it convenient can always object. So there will never be consensus for change. If there is any objection at all, no matter how ill-founded, the status quo will always win.
&lt;p&gt;This is where governance comes in.
&lt;h3&gt;&lt;a name="governance-is-like-backups-we-need-to-practice-it"&gt;Governance is like backups: we need to practice it&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Governance processes are the backstop for when discussions, and then negotiations, fail, and people still don&amp;rsquo;t see eye to eye.
&lt;p&gt;In a healthy community, everyone needs to know how the governance works and what the rules are. The participants need to accept the system&amp;rsquo;s legitimacy. Everyone, including the losing side, must be prepared to accept and implement (or, at least not obstruct) whatever the decision is, and hopefully live with it and stay around.
&lt;p&gt;That means we need to &lt;em&gt;practice&lt;/em&gt; our governance processes. We can&amp;rsquo;t just leave them for the day we have a huge and controversial decision to make. If we do that, then when it comes to the crunch we&amp;rsquo;ll have toxic rows where no-one can agree the rules; where determined people bend the rules to fit their outcome; and where afterwards people feel like the whole thing was horrible and unfair.
&lt;p&gt;So our decisionmaking bodies and roles need to be making decisions, as a matter of routine, and we need to get used to that.
&lt;p&gt;First-line decisionmaking bodies should be making decisions &lt;em&gt;frequently&lt;/em&gt;. Last-line appeal mechanisms (large-scale votes, for example) are naturally going to be exercised more rarely, but they must &lt;em&gt;happen&lt;/em&gt;, be seen as legitimate, and their outcomes must be implemented in full.
&lt;h3&gt;&lt;a name="governance-should-usually-be-routine-and-boring"&gt;Governance should usually be routine and boring&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When governance is working well it&amp;rsquo;s quite boring.
&lt;p&gt;People offer their input, and are heard. Angles are debated, and concerns are addressed. If agreement still isn&amp;rsquo;t reached, the committee, or elected leader, makes a decision.
&lt;p&gt;Hopefully everyone thinks the leadership is legitimate, and that it properly considered and heard their arguments, and made the decision for good reasons.
&lt;p&gt;Hopefully the losing side can still get their work done (and make their own computer work the way they want); so while they will be disappointed, they can live with the outcome.
&lt;p&gt;Many human institutions manage this most of the time. It does take some knowledge about principles of governance, and ideally some experience.
&lt;h3&gt;&lt;a name="governance-means-deciding-not-just-mediating"&gt;Governance means deciding, not just mediating&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;By &lt;em&gt;making decisions&lt;/em&gt; I mean exercising their authority to rule on an actual disagreement: one that wasn&amp;rsquo;t resolved by debate or negotiation. Governance processes by definition involve &lt;em&gt;deciding&lt;/em&gt;, not just mediating. It&amp;rsquo;s not governance if we&amp;rsquo;re advising or cajoling: in that case, we&amp;rsquo;re back to demanding consensus. Governance is necessary precisely when consensus is not achieved.
&lt;p&gt;If the governance systems are to mean anything, they must be able to &lt;em&gt;(over)rule&lt;/em&gt;; that means &lt;em&gt;(over)ruling&lt;/em&gt; must be &lt;em&gt;normal&lt;/em&gt; and &lt;em&gt;accepted&lt;/em&gt;.
&lt;p&gt;Otherwise, when the we need to overrule, we&amp;rsquo;ll find that we can&amp;rsquo;t, because we lack the collective practice.
&lt;p&gt;To be legitimate (and seen as legitimate) decisions must usually be made based on the &lt;em&gt;merits&lt;/em&gt;, not on participants&amp;rsquo; status, and not only on process questions.
&lt;h3&gt;&lt;a name="on-the-autonomy-of-the-programmer"&gt;On the autonomy of the programmer&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Many programmers seem to find the very concept of governance, and binding decisionmaking, deeply uncomfortable.
&lt;p&gt;Ultimately, it means sometimes overruling someone&amp;rsquo;s technical decision. As programmers and maintainers we naturally see how this erodes our autonomy.
&lt;p&gt;But we have all seen projects where the maintainers are unpleasant, obstinate, or destructive. We have all found this frustrating. Software is all interconnected, and one programmer&amp;rsquo;s bad decisions can cause problems for many of the rest of us. We exasperate, &amp;ldquo;why won&amp;rsquo;t they just do the right thing&amp;rdquo;. This is futile. People have never &amp;ldquo;just&amp;rdquo;ed and they&amp;rsquo;re not going to start &amp;ldquo;just&amp;rdquo;ing now. So often the boot is on the other foot.
&lt;p&gt;More broadly, as software developers, we have a responsibility to our users, and a duty to write code that does good rather than ill in the world. We &lt;em&gt;ought&lt;/em&gt; to be accountable. (And not just to capitalist bosses!)
&lt;p&gt;Governance mechanisms are the answer.
&lt;p&gt;(No, forking anything but the smallest project is very rarely a practical answer.)
&lt;h3&gt;&lt;a name="mitigate-the-consequences-of-decisions-retain-flexibility"&gt;Mitigate the consequences of decisions &amp;mdash; retain flexibility&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In software, it is often possible to soften the bad social effects of a controversial decision, by retaining flexibility. With a bit of extra work, we can often provide hooks, non-default configuration options, or plugin arrangements.
&lt;p&gt;If we can convert the question from &amp;ldquo;how will the software always behave&amp;rdquo; into merely &amp;ldquo;what should the default be&amp;rdquo;, we can often save ourselves a lot of drama.
&lt;p&gt;So it is often worth keeping even suboptimal or untidy features or options, if people want to use them and are willing to maintain them.
&lt;p&gt;There is a tradeoff here, of course. But Free Software projects often significantly under-value the social benefits of keeping everyone happy. Wrestling software &amp;mdash; even crusty or buggy software &amp;mdash; is a lot more fun than having unpleasant arguments.
&lt;h3&gt;&lt;a name="but-dont-do-decisionmaking-like-a-corporation"&gt;But don&amp;rsquo;t do decisionmaking like a corporation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Many programmers&amp;rsquo; experience of formal decisionmaking is from their boss at work. But corporations are often a very bad example.
&lt;p&gt;They typically don&amp;rsquo;t have as much trouble actually &lt;em&gt;making&lt;/em&gt; decisions, but the actual decisions are often terrible, and not just because corporations&amp;rsquo; goals are often bad.
&lt;p&gt;You get to be a decisionmaker in a corporation by spouting plausible nonsense, sounding confident, buttering up the even-more-vacuous people further up the chain, and sometimes by sabotaging your rivals. Corporate senior managers are hardly ever held accountable &amp;mdash; typically the effects of their tenure are only properly felt well after they&amp;rsquo;ve left to mess up somewhere else.
&lt;p&gt;We should select our leaders more wisely, and base decisions on substance.
&lt;h2&gt;&lt;a name="if-you-wont-do-politics-politics-will-do-you"&gt;If you won&amp;rsquo;t do politics, politics will do you&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As a participant in a project, or a society, you can of course opt out of getting involved in politics.
&lt;p&gt;You can opt out of learning how to do politics generally, and opt out of understanding your project&amp;rsquo;s governance structures. You can opt out of making judgements about disputed questions, and tell yourself &amp;ldquo;&lt;a href="https://en.wikipedia.org/wiki/False_balance"&gt;there&amp;rsquo;s merit on both sides&lt;/a&gt;&amp;rdquo;.
&lt;p&gt;You can hate politicians indiscriminately, and criticise anyone you see doing politics.
&lt;p&gt;If you do this, then you are abdicating your decisionmaking authority, to those who are the most effective manipulators, or the most committed to getting their way. You&amp;rsquo;re tacitly supporting the existing power bases. You&amp;rsquo;re ceding power to the best liars, to those with the least scruples, and to the people who are most motivated by dominance. This is precisely the opposite of what you wanted.
&lt;p&gt;If enough people won&amp;rsquo;t do politics, and hate anyone who does, your discussion spaces will be reduced to a battleground of only the hardiest and the most toxic.
&lt;h3&gt;&lt;a name="if-you-dont-see-the-politics-its-still-happening"&gt;If you don&amp;rsquo;t see the politics, it&amp;rsquo;s still happening&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If your governance systems don&amp;rsquo;t work, then there is no effective redress against bad or even malicious decisions. Your roleholders and subteams are unaccountable power centres.
&lt;p&gt;Power radically distorts every human relationship, and it takes great strength of character for an unaccountable power centre not to eventually become an unaccountable toxic cabal.
&lt;p&gt;So if you have a reasonable sized community, but don&amp;rsquo;t see your formal governance systems working &amp;mdash; people debating things, votes, leadership making explicit decisions &amp;mdash; that doesn&amp;rsquo;t mean everything is fine, and all the decisions are great, and there&amp;rsquo;s no politics happening.
&lt;p&gt;It just means that most of your community have given up on the official process. It also probably means that some parts of your project have formed toxic and unaccountable cabals. Those who won&amp;rsquo;t put up with that will leave.
&lt;p&gt;The same is true if the only governance actions that ever happen are massive drama. That means that only the most determined victim of a bad decision, will even consider using such a process.
&lt;h2&gt;&lt;a name="conclusions"&gt;Conclusions&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;p&gt;Respect and support the people who are trying to fix things with politics.

&lt;li&gt;&lt;p&gt;Be informed, and, where appropriate, involved.

&lt;li&gt;&lt;p&gt;If you are in a position of authority, be willing to &lt;em&gt;exercise&lt;/em&gt; that authority. Do more than just mediating to try to get consensus.

&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=19879" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:19480</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/19480.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=19480"/>
    <title>Rust is indeed woke</title>
    <published>2025-03-28T12:59:43Z</published>
    <updated>2025-03-28T17:09:57Z</updated>
    <category term="politics"/>
    <category term="rust"/>
    <category term="computers"/>
    <dw:security>public</dw:security>
    <dw:reply-count>3</dw:reply-count>
    <content type="html">&lt;p&gt;Rust, and resistance to it in some parts of the Linux community, has been in my feed recently. One undercurrent seems to be the notion that Rust is woke (and should therefore be rejected as part of culture wars).
&lt;p&gt;I&amp;rsquo;m going to argue that Rust, the language, &lt;em&gt;is&lt;/em&gt; woke. So the opponents are right, in that sense. Of course, as ever, dissing something for being woke is nasty and fascist-adjacent.
&lt;ul&gt;&lt;li&gt;&lt;a href="#community"&gt;Community&lt;/a&gt;
&lt;li&gt;&lt;a href="#technological-values---particularly-compared-to-cc"&gt;Technological values - particularly, compared to C/C++&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#ostensible-values"&gt;Ostensible values&lt;/a&gt;
&lt;li&gt;&lt;a href="#attitude-to-the-programmers-mistakes"&gt;Attitude to the programmer&amp;rsquo;s mistakes&lt;/a&gt;
&lt;li&gt;&lt;a href="#the-ideology-of-the-hardcore-programmer"&gt;The ideology of the hardcore programmer&lt;/a&gt;
&lt;li&gt;&lt;a href="#memory-safety-as-a-power-struggle"&gt;Memory safety as a power struggle&lt;/a&gt;
&lt;li&gt;&lt;a href="#memory-safety-via-rust-as-a-power-struggle"&gt;Memory safety &lt;em&gt;via Rust&lt;/em&gt; as a power struggle&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#notes"&gt;Notes&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#this-is-not-a-riir-manifesto"&gt;This is not a RIIR manifesto&lt;/a&gt;
&lt;li&gt;&lt;a href="#disclosure"&gt;Disclosure&lt;/a&gt;
&lt;li&gt;&lt;a href="#on-the-meaning-of-woke"&gt;On the meaning of &amp;ldquo;woke&amp;rdquo;&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#pithy-conclusion"&gt;Pithy conclusion&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h2&gt;&lt;a name="community"&gt;Community&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The obvious way that Rust may seem woke is that it has the trappings, and many of the attitudes and outcomes, of a modern, nice, FLOSS community. Rust certainly does better than toxic environments like the Linux kernel, or Debian. This is reflected in a higher proportion of contributors from various kinds of minoritised groups. But Rust is &lt;em&gt;not&lt;/em&gt; outstanding in this respect. It certainly has its problems. Many other projects do as well or better.
&lt;p&gt;And this is well-trodden ground. I have something more interesting to say:
&lt;h2&gt;&lt;a name="technological-values---particularly-compared-to-cc"&gt;Technological values - particularly, compared to C/C++&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Rust is &lt;em&gt;woke technology&lt;/em&gt; that embodies a &lt;em&gt;woke understanding&lt;/em&gt; of what it means to be a programming language.
&lt;h3&gt;&lt;a name="ostensible-values"&gt;Ostensible values&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s start with Rust&amp;rsquo;s strapline:
&lt;blockquote&gt;&lt;p&gt;A language empowering everyone to build reliable and efficient software.
&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Surprisingly, this motto is not mere marketing puff. For Rustaceans, it is a key goal which strongly influences day-to-day decisions (big and small).
&lt;p&gt;&lt;strong&gt;Empowering everyone&lt;/strong&gt; is a key aspect of this, which aligns with my own personal values. In the Rust community, we care about &lt;em&gt;empowerment&lt;/em&gt;. We are trying to help liberate our users. And we want to empower &lt;em&gt;everyone&lt;/em&gt; because everyone is entitled to technological autonomy. (For a programming language, empowering individuals means empowering their communities, of course.)
&lt;p&gt;This is all very airy-fairy, but it has concrete consequences:
&lt;h3&gt;&lt;a name="attitude-to-the-programmers-mistakes"&gt;Attitude to the programmer&amp;rsquo;s mistakes&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In Rust we consider it a key part of our job to help the programmer avoid mistakes; to limit the consequences of mistakes; and to guide programmers in useful directions.
&lt;p&gt;If you write a bug in your Rust program, Rust doesn&amp;rsquo;t blame you. Rust asks &amp;ldquo;how could the compiler have spotted that bug&amp;rdquo;.
&lt;p&gt;This is in sharp contrast to C (and C++). C nowadays is an insanely hostile programming environment. A C compiler relentlessly scours your program for any place where you may have violated C&amp;rsquo;s almost incomprehensible rules, so that it can compile your apparently-correct program into a buggy executable. And then the bug is considered your fault.
&lt;p&gt;These aren&amp;rsquo;t just attitudes implicitly embodied in the software. They are concrete opinions expressed by compiler authors, and also by language proponents. In other words:
&lt;p&gt;Rust sees programmers writing bugs as a systemic problem, which must be addressed by improvements to the environment and the system. The toxic parts of the C and C++ community see bugs as moral failings by individual programmers.
&lt;p&gt;Sound familiar?
&lt;h3&gt;&lt;a name="the-ideology-of-the-hardcore-programmer"&gt;The ideology of the hardcore programmer&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Programming has long suffered from the myth of the &amp;ldquo;rockstar&amp;rdquo;. Silicon Valley techbro culture loves this notion.
&lt;p&gt;In reality, though, modern information systems are far too complicated for a single person. Developing systems is a &lt;em&gt;team sport&lt;/em&gt;. Nontechnical, and technical-adjacent, skills are vital: clear but friendly communication; obtaining and incorporating the insights of every member of your team; willingness to be challenged. Community building. Collaboration. Governance.
&lt;p&gt;The hardcore C community embraces the rockstar myth: they imagine that a few super-programmers (or super-reviewers) are able to spot bugs, just by being so brilliant. Of course this doesn&amp;rsquo;t actually work at all, as we can see from the atrocious bugfest that is the Linux kernel.
&lt;p&gt;These &amp;ldquo;rockstars&amp;rdquo; want us to believe that there is a steep hierarchy in programmming; that they are at the top of this hierarchy; and that being nice isn&amp;rsquo;t important.
&lt;p&gt;Sound familiar?
&lt;h3&gt;&lt;a name="memory-safety-as-a-power-struggle"&gt;Memory safety as a power struggle&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Much of the modern crisis of software reliability arises from memory-unsafe programming languages, mostly C and C++.
&lt;p&gt;Addressing this is a big job, requiring many changes. This threatens powerful interests; notably, corporations who want to keep shipping junk. (See also, conniptions over the EU Product Liability Directive.)
&lt;p&gt;The harms of this serious problem mostly fall on society at large, but the convenience of carrying on as before benefits existing powerful interests.
&lt;p&gt;Sound familiar?
&lt;h3&gt;&lt;a name="memory-safety-via-rust-as-a-power-struggle"&gt;Memory safety &lt;em&gt;via Rust&lt;/em&gt; as a power struggle&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Addressing this problem &lt;em&gt;via Rust&lt;/em&gt; is a direct threat to the power of established C programmers such as gatekeepers in the Linux kernel. Supplanting C means they will have to learn new things, and jostle for status against better Rustaceans, or &lt;a href="https://lwn.net/Articles/1011819/"&gt;be replaced&lt;/a&gt;. More broadly, Rust shows that it is practical to write fast, reliable, software, and that this does not need (mythical) &amp;ldquo;rockstars&amp;rdquo;.
&lt;p&gt;So established C programmer &amp;ldquo;experts&amp;rdquo; are existing vested interests, whose power is undermined by (this approach to) tackling this serious problem.
&lt;p&gt;Sound familiar?
&lt;h2&gt;&lt;a name="notes"&gt;Notes&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;a name="this-is-not-a-riir-manifesto"&gt;This is not a RIIR manifesto&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m &lt;em&gt;not&lt;/em&gt; saying we should rewrite all the world&amp;rsquo;s C in Rust. We should not try to do that.
&lt;p&gt;Rust is often a good choice for new code, or when a rewrite or substantial overhaul is needed anyway. But we&amp;rsquo;re going to need other techniques to deal with all of our existing C. &lt;a href="Capability_Hardware_Enhanced_RISC_Instructions"&gt;CHERI&lt;/a&gt; is a very promising approach. Sandboxing, emulation and automatic translation are other possibilities. The problem is a big one and we need a toolkit, not a magic bullet.
&lt;p&gt;But as for Linux: it is a scandal that substantial new drivers and subsystems are still being written in C. We could have been using Rust for new code throughout Linux years ago, and avoided very many bugs. Those bugs are doing real harm. This is not OK.
&lt;h3&gt;&lt;a name="disclosure"&gt;Disclosure&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I first learned C from K&amp;amp;R I in 1989. I spent the first three decades of my life as a working programmer writing lots and lots of C. I&amp;rsquo;ve written C++ too. I used to consider myself an expert C programmer, but nowadays my C is a bit rusty and out of date. Why is my C rusty? Because I found Rust, and immediately liked and adopted it (despite its many faults).
&lt;p&gt;I like Rust because I care that the software I write &lt;em&gt;actually works&lt;/em&gt;: I care that my code doesn&amp;rsquo;t do harm in the world.
&lt;h3&gt;&lt;a name="on-the-meaning-of-woke"&gt;On the meaning of &amp;ldquo;woke&amp;rdquo;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The original meaning of &amp;ldquo;woke&amp;rdquo; is something much more specific, to do with racism. For the avoidance of doubt, I don&amp;rsquo;t think Rust is particularly antiracist.
&lt;p&gt;I&amp;rsquo;m using &amp;ldquo;woke&amp;rdquo; (like Rust&amp;rsquo;s opponents are) in the much broader, and now much more prevalent, culture wars sense.
&lt;h2&gt;&lt;a name="pithy-conclusion"&gt;Pithy conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re a senior developer who knows only C/C++, doesn&amp;rsquo;t want their authority challenged, and doesn&amp;rsquo;t want to have to learn how to write better software, you should hate Rust.
&lt;p&gt;Also you should be fired.
&lt;hr&gt;
&lt;address&gt;
Edited 2025-03-28 17:10 UTC to fix minor problems and add a new note about the meaning of the word "woke".
&lt;/address&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=19480" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:19395</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/19395.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=19395"/>
    <title>derive-deftly 1.0.0 - Rust derive macros, the easy way</title>
    <published>2025-02-11T21:14:07Z</published>
    <updated>2025-02-11T21:16:33Z</updated>
    <category term="computers"/>
    <category term="rust"/>
    <category term="derive-deftly"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;p&gt;&lt;a href="https://docs.rs/derive-deftly/latest/derive_deftly/"&gt;derive-deftly&lt;/a&gt; 1.0 is released.
&lt;p&gt;derive-deftly is a template-based derive-macro facility for Rust. It has been a great success. Your codebase may benefit from it too!
&lt;p&gt;Rust programmers will appreciate its power, flexibility, and consistency, compared to &lt;code&gt;macro_rules&lt;/code&gt;; and its convenience and simplicity, compared to proc macros.
&lt;p&gt;Programmers coming to Rust from scripting languages will appreciate derive-deftly&amp;rsquo;s convenient automatic code generation, which works as a kind of compile-time introspection.
&lt;ul&gt;&lt;li&gt;&lt;a href="#rusts-two-main-macro-systems"&gt;Rust&amp;rsquo;s two main macro systems&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#macro_rules"&gt;&lt;code&gt;macro_rules!&lt;/code&gt;&lt;/a&gt;
&lt;li&gt;&lt;a href="#proc-macros"&gt;proc macros&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#derive-deftly-to-the-rescue"&gt;derive-deftly to the rescue&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#example"&gt;Example&lt;/a&gt;
&lt;li&gt;&lt;a href="#special-purpose-derive-macros-are-now-worthwhile"&gt;Special-purpose derive macros are now worthwhile!&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#stability-without-stagnation"&gt;Stability without stagnation&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;p&gt;
&lt;h2&gt;&lt;a name="rusts-two-main-macro-systems"&gt;Rust&amp;rsquo;s two main macro systems&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m often a fan of metaprogramming, including macros. They can help &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;remove duplication&lt;/a&gt; and flab, which are often the enemy of correctness.
&lt;p&gt;Rust has two macro systems. derive-deftly offers much of the power of the more advanced (proc_macros), while beating the simpler one (macro_rules) at its own game for ease of use.
&lt;p&gt;(Side note: Rust has at least three other ways to do metaprogramming: generics; &lt;code&gt;build.rs&lt;/code&gt;; and, multiple module inclusion via &lt;code&gt;#[path=]&lt;/code&gt;. These are beyond the scope of this blog post.)
&lt;h3&gt;&lt;a name="macro_rules"&gt;&lt;code&gt;macro_rules!&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/book/ch19-06-macros.html#declarative-macros-with-macro_rules-for-general-metaprogramming"&gt;&lt;code&gt;macro_rules!&lt;/code&gt;&lt;/a&gt; aka &amp;ldquo;pattern macros&amp;rdquo;, &amp;ldquo;declarative macros&amp;rdquo;, or sometimes &amp;ldquo;macros by example&amp;rdquo; are the simpler kind of Rust macro.
&lt;p&gt;They involve writing a sort-of-BNF pattern-matcher, and a template which is then expanded with substitutions from the actual input. If your macro wants to accept comma-separated lists, or other simple kinds of input, this is OK. But often we want to emulate a &lt;code&gt;#[derive(...)]&lt;/code&gt; macro: e.g., to define code based on a struct, handling each field. Doing that with macro_rules is very awkward:
&lt;p&gt;&lt;code&gt;macro_rules!&lt;/code&gt;&amp;rsquo;s pattern language doesn&amp;rsquo;t have a cooked way to match a data structure, so you have to hand-write a matcher for Rust syntax, in each macro. Writing such a matcher is very hard in the general case, because &lt;code&gt;macro_rules&lt;/code&gt; lacks features for matching important parts of Rust syntax (notably, generics). (If you &lt;em&gt;really&lt;/em&gt; need to, there&amp;rsquo;s a &lt;a href="https://fprijate.github.io/tlborm/pat-incremental-tt-munchers.html"&gt;horrible technique&lt;/a&gt; as a workaround.)
&lt;p&gt;And, the invocation syntax for the macro is awkward: you must enclose the whole of the struct in &lt;code&gt;my_macro! { }&lt;/code&gt;. This makes it hard to apply more than one macro to the same struct, and produces rightward drift.
&lt;p&gt;Enclosing the struct this way means the macro must reproduce its input - so it can have bugs where it mangles the input, perhaps subtly. This also means the reader cannot be sure precisely whether the macro modifies the struct itself. In Rust, the types and data structures are often the key places to go to understand a program, so this is a significant downside.
&lt;p&gt;&lt;code&gt;macro_rules&lt;/code&gt; also has various other weird deficiencies too specific to list here.
&lt;p&gt;Overall, compared to (say) the C preprocessor, it&amp;rsquo;s great, but programmers used to the power of Lisp macros, or (say) metaprogramming in Tcl, will quickly become frustrated.
&lt;h3&gt;&lt;a name="proc-macros"&gt;proc macros&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Rust&amp;rsquo;s &lt;a href="https://doc.rust-lang.org/proc_macro/index.html"&gt;second macro system&lt;/a&gt; is much more advanced. It is a fully general system for processing and rewriting code. The macro&amp;rsquo;s implementation is Rust code, which takes the macro&amp;rsquo;s input as arguments, in the form of &lt;a href="https://doc.rust-lang.org/proc_macro/enum.TokenTree.html"&gt;Rust tokens&lt;/a&gt;, and returns Rust tokens to be inserted into the actual program.
&lt;p&gt;This approach is more similar to Common Lisp&amp;rsquo;s macros than to most other programming languages&amp;rsquo; macros systems. It is extremely powerful, and is used to implement many very widely used and powerful facilities. In particular, proc macros can be applied to data structures with &lt;code&gt;#[derive(...)]&lt;/code&gt;. The macro receives the data structure, in the form of Rust tokens, and returns the code for the new implementations, functions etc.
&lt;p&gt;This is used very heavily in the standard library for basic features like &lt;code&gt;#[derive(Debug)]&lt;/code&gt; and &lt;code&gt;Clone&lt;/code&gt;, and for important libraries like &lt;a href="https://serde.rs/"&gt;&lt;code&gt;serde&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://lib.rs/crates/strum"&gt;&lt;code&gt;strum&lt;/code&gt;&lt;/a&gt;.
&lt;p&gt;But, it is a complete pain in the backside to &lt;em&gt;write&lt;/em&gt; and &lt;em&gt;maintain&lt;/em&gt; a proc_macro.
&lt;p&gt;The Rust types and functions you deal with in your macro are very low level. You must manually handle every possible case, with runtime conditions and pattern-matching. Error handling and recovery is so nontrivial there are macro-writing &lt;a href="https://lib.rs/crates/proc-macro-error"&gt;libraries&lt;/a&gt; and even &lt;a href="https://lib.rs/crates/manyhow"&gt;more macros&lt;/a&gt; to help. Unlike a Lisp codewalker, a Rust proc macro must deal with Rust&amp;rsquo;s highly complex syntax. You will probably end up dealing with &lt;a href="https://lib.rs/crates/syn"&gt;syn&lt;/a&gt;, which is a complete Rust parsing library, separate from the compiler; syn is capable and comprehensive, but a proc macro must still contain a lot of often-intricate code.
&lt;p&gt;There are build/execution environment problems. The proc_macro code can&amp;rsquo;t live with your application; you have to put the proc macros in a separate cargo package, complicating your build arrangements. The proc macro package environment is weird: you can&amp;rsquo;t test it separately, without &lt;a href="https://lib.rs/crates/proc-macro2"&gt;jumping through hoops&lt;/a&gt;. Debugging can be awkward. Proper tests can only realistically be done with the help of complex &lt;a href="https://lib.rs/crates/macrotest"&gt;additional&lt;/a&gt; &lt;a href="https://lib.rs/crates/trybuild"&gt;tools&lt;/a&gt;, and will involve a pinned version of Nightly Rust.
&lt;h2&gt;&lt;a name="derive-deftly-to-the-rescue"&gt;derive-deftly to the rescue&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;derive-deftly lets you use a write a &lt;code&gt;#[derive(...)]&lt;/code&gt; macro, driven by a data structure, without wading into any of that stuff.
&lt;p&gt;Your macro definition is a template in a simple syntax, with predefined &lt;code&gt;$&lt;/code&gt;-substitutions for the various parts of the input data structure.
&lt;h3&gt;&lt;a name="example"&gt;Example&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s a &lt;a href="https://salsa.debian.org/dgit-team/tag2upload-service-manager/-/blob/30bf4969b31df2802e7642330d607e61e73d5b5c/src/o2m_tracker.rs#L84"&gt;real-world&lt;/a&gt; &lt;a href="https://salsa.debian.org/dgit-team/tag2upload-service-manager/-/blob/30bf4969b31df2802e7642330d607e61e73d5b5c/src/db_data.rs#L83"&gt;example&lt;/a&gt; from a personal project:
&lt;pre&gt;&lt;code&gt;define_derive_deftly! {
    export UpdateWorkerReport:
    impl $ttype {
        pub fn update_worker_report(&amp;amp;self, wr: &amp;amp;mut WorkerReport) {
            $(
                ${when fmeta(worker_report)}
                wr.$fname = Some(self.$fname.clone()).into();
            )
        }
    }
}&lt;/code&gt;&lt;/pre&gt; &lt;pre&gt;&lt;code&gt;#[derive(Debug, Deftly, Clone)]
...
#[derive_deftly(UiMap, UpdateWorkerReport)]
pub struct JobRow {
    ...
    #[deftly(worker_report)]
    pub status: JobStatus,
    pub processing: NoneIsEmpty&amp;lt;ProcessingInfo&amp;gt;,
    #[deftly(worker_report)]
    pub info: String,
    pub duplicate_of: Option&amp;lt;JobId&amp;gt;,
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a nice example, also, of how using a macro can avoid bugs. Implementing this update by hand without a macro would involve a lot of cut-and-paste. When doing that cut-and-paste it can be very easy to accidentally write bugs where you forget to update some parts of each of the copies:
&lt;pre&gt;&lt;code&gt;    pub fn update_worker_report(&amp;amp;self, wr: &amp;amp;mut WorkerReport) {
        wr.status = Some(self.status.clone()).into();
        wr.info = Some(self.status.clone()).into();
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Spot the mistake? We copy &lt;code&gt;status&lt;/code&gt; to &lt;code&gt;info&lt;/code&gt;. Bugs like this are extremely common, and not always found by the type system. derive-deftly can make it much easier to make them impossible.
&lt;h3&gt;&lt;a name="special-purpose-derive-macros-are-now-worthwhile"&gt;Special-purpose derive macros are now worthwhile!&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Because of the difficult and cumbersome nature of proc macros, very few projects have site-specific, special-purpose &lt;code&gt;#[derive(...)]&lt;/code&gt; macros.
&lt;p&gt;The &lt;a href="https://arti.torproject.org/"&gt;Arti&lt;/a&gt; &lt;a href="https://gitlab.torproject.org/tpo/core/arti"&gt;codebase&lt;/a&gt; has &lt;strong&gt;no&lt;/strong&gt; bespoke proc macros, across its 240kloc and 86 crates. (We did &lt;a href="https://lib.rs/crates/derive_builder_fork_arti"&gt;fork&lt;/a&gt; one upstream proc macro package to add a feature we needed.) I have only &lt;em&gt;one&lt;/em&gt; bespoke, case-specific, proc macro amongst all of my personal Rust projects; it predates derive-deftly.
&lt;p&gt;Since we have started using derive-deftly in Arti, it has become an important tool in our toolbox. We have &lt;strong&gt;37&lt;/strong&gt; bespoke derive macros, done with derive-deftly. Of these, 9 are exported for use by downstream crates. (For comparison there are 176 macro_rules macros.)
&lt;p&gt;In my most recent &lt;a href="https://salsa.debian.org/dgit-team/tag2upload-service-manager"&gt;personal Rust project&lt;/a&gt;, I have &lt;strong&gt;22&lt;/strong&gt; bespoke derive macros, done with with derive-deftly, and 19 macro_rules macros.
&lt;p&gt;derive-deftly macros are easy and straightforward enough that they can be used as readily as macro_rules macros. Indeed, they are often &lt;em&gt;clearer&lt;/em&gt; than a macro_rules macro.
&lt;h2&gt;&lt;a name="stability-without-stagnation"&gt;Stability without stagnation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;derive-deftly is already highly capable, and can solve many advanced problems.
&lt;p&gt;It is mature software, well tested, with excellent documentation, comprising both comprehensive &lt;a href="https://docs.rs/derive-deftly/latest/derive_deftly/index.html#overall-toc"&gt;reference material&lt;/a&gt; and the &lt;a href="https://diziet.pages.torproject.net/rust-derive-deftly/latest/guide/"&gt;walkthrough-structured user guide&lt;/a&gt;.
&lt;p&gt;But declaring it 1.0 doesn&amp;rsquo;t mean that it won&amp;rsquo;t improve further.
&lt;p&gt;Our &lt;a href="https://gitlab.torproject.org/Diziet/rust-derive-deftly/-/issues/?sort=updated_desc&amp;amp;state=opened&amp;amp;first_page_size=100"&gt;ticket tracker&lt;/a&gt; has a laundry list of possible features. We&amp;rsquo;ll sometimes be cautious about committing to these, so we&amp;rsquo;ve added a &lt;a href="https://docs.rs/derive-deftly/1.0.0/derive_deftly/doc_changelog/index.html#t:beta"&gt;&lt;code&gt;beta&lt;/code&gt;&lt;/a&gt; feature flag, for opting in to less-stable features, so that we can prototype things without painting ourselves into a corner. And, we intend to further develop the Guide.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=19395" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:19151</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/19151.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=19151"/>
    <title>The Rust Foundation's 2nd bad draft trademark policy</title>
    <published>2024-11-20T12:50:20Z</published>
    <updated>2024-11-20T12:50:34Z</updated>
    <category term="rust"/>
    <category term="legal"/>
    <dw:security>public</dw:security>
    <dw:reply-count>2</dw:reply-count>
    <content type="html">&lt;p&gt;tl;dr: The Rust Foundation&amp;rsquo;s new trademark policy still forbids unapproved modifications: this would &lt;strong&gt;forbid&lt;/strong&gt; both &lt;strong&gt;the Rust Community&amp;rsquo;s own development work(!)&lt;/strong&gt; and normal Free Software distribution practices.
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;p&gt;
&lt;h3&gt;&lt;a name="background"&gt;Background&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In April 2023 &lt;a href="https://diziet.dreamwidth.org/14929.html"&gt;I wrote&lt;/a&gt; about the Rust Foundation&amp;rsquo;s ham-fisted and misguided attempts to update the Rust trademark policy. This &lt;a href="https://blog.rust-lang.org/inside-rust/2023/04/12/trademark-policy-draft-feedback.html"&gt;turned into drama&lt;/a&gt;.
&lt;h3&gt;&lt;a name="the-new-draft"&gt;The new draft&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Recently, the Foundation published a &lt;a href="https://drive.usercontent.google.com/download?id=1hjTx11Fb-4W7RQLmp3R8BLDACc7zxIpG&amp;amp;export=download"&gt;new draft&lt;/a&gt;. It&amp;rsquo;s considerably less bad, but the most serious problem, which I identified last year, remains.
&lt;p&gt;It prevents redistribution of modified versions of Rust, without pre-approval from the Rust Foundation. (Subject to some limited exceptions.) The people who wrote this evidently haven&amp;rsquo;t realised that distributing modified versions is how free software development works. Ie, &lt;strong&gt;the draft Rust trademark policy even forbids making a github branch for an MR to contribute to Rust!&lt;/strong&gt;
&lt;p&gt;It&amp;rsquo;s also very likely unacceptable to Debian. Rust is still on track to repeat the &lt;a href="https://en.wikipedia.org/wiki/Iceweasel"&gt;Firefox/Iceweasel debacle&lt;/a&gt;.
&lt;p&gt;Below is a copy of my formal response to the &lt;a href="https://blog.rust-lang.org/2024/11/06/trademark-update.html"&gt;consultation&lt;/a&gt;. The consultation closes at 07:59:00 UTC tomorrow (21st November), ie, at the end of today (Wednesday) US Pacific time, so if you want to reply, do so quickly.
&lt;h3&gt;&lt;a name="my-consultation-response"&gt;My consultation response&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;Hi. My name is Ian Jackson. I write as a Rust contributor and as a Debian Developer with first-hand experience of Debian&amp;rsquo;s approach to trademarks. (But I am not a member of the Debian Rust Packaging Team.)
&lt;p&gt;Your form invites me to state any blocking concerns. I&amp;rsquo;m afraid I have one:
&lt;p&gt;PROBLEM
&lt;p&gt;The policy on distributing modified versions of Rust (page 4, 8th bullet) is far too restrictive.
&lt;p&gt;PROBLEM - ASPECT 1
&lt;p&gt;On its face the policy forbids making a clone of the Rust repositories on a git forge, and pushing a modified branch there. That &lt;em&gt;is&lt;/em&gt; publicly distributing a modified version of Rust.
&lt;p&gt;I.e., the current policy forbids the Rust&amp;rsquo;s community&amp;rsquo;s own development workflow!
&lt;p&gt;PROBLEM - ASPECT 2
&lt;p&gt;The policy also does not meet the needs of Software-Freedom-respecting downstreams, including community Linux distributions such as Debian.
&lt;p&gt;There are two scenarios (fuzzy, and overlapping) which provide a convenient framing to discuss this:
&lt;p&gt;Firstly, in practical terms, Debian may need to backport bugfixes, or sometimes other changes. Sometimes Debian will want to pre-apply bugfixes or changes that have been contributed by users, and are intended eventually to go upstream, but are not included upstream in official Rust yet. This is a routine activity for a distribution. The policy, however, forbids it.
&lt;p&gt;Secondly, Debian, as a point of principle, requires the ability to diverge from upstream if and when Debian decides that this is the right choice for Debian&amp;rsquo;s users. The freedom to modify is a key principle of Free Software. This includes making changes that the upstream project disapproves of. Some examples of this, where Debian has made changes, that upstream do not approve of, have included things like: removing user-tracking code, or disabling obsolescence &amp;ldquo;timebombs&amp;rdquo; that stop a particular version working after a certain date.
&lt;p&gt;Overall, while alignment in values between Debian and Rust seems to be very good right now, modifiability it is a matter of non-negotiable principle for Debian. The 8th bullet point on page 4 of the PDF does not give Debian (and Debian&amp;rsquo;s users) these freedoms.
&lt;p&gt;POSSIBLE SOLUTIONS
&lt;p&gt;Other formulations, or an additional permission, seem like they would be able to meet the needs of both Debian &lt;em&gt;and&lt;/em&gt; Rust.
&lt;p&gt;The first thing to recognise is that forbidding modified versions is probably not necessary to prevent language ecosystem fragmentation. Many other programming languages are distributed under fully Free Software licences without such restrictive trademark policies. (For example, Python; I&amp;rsquo;m sure a thorough survey would find many others.)
&lt;p&gt;The scenario that would be most worrying for Rust would be &amp;ldquo;embrace - extend - extinguish&amp;rdquo;. In projects with a copyleft licence, this is not a concern, but Rust is permissively licenced. However, one way to address this would be to add an additional permission for modification that permits distribution of modified versions &lt;em&gt;without permission, but if the modified source code is also provided, under the original Rust licence&lt;/em&gt;.
&lt;p&gt;I suggest therefore adding the following 2nd sub-bullet point to the 8th bullet on page 4:
&lt;ul&gt;&lt;li&gt;changes which are shared, in source code form, with all recipients of the modified software, and publicly licenced under the same licence as the official materials.
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;This means that downstreams who fear copyleft have the option of taking Rust&amp;rsquo;s permissive copyright licence at face value, but are limited in the modifications they may make, unless they rename. Conversely downstreams such as Debian who wish to operate as part of the Free Software ecosystem can freely make modifications.
&lt;p&gt;It also, obviously, covers the Rust Community&amp;rsquo;s own development work.
&lt;p&gt;NON-SOLUTIONS
&lt;p&gt;Some upstreams, faced with this problem, have offered Debian a special permission: ie, said that it would be OK for &lt;em&gt;Debian&lt;/em&gt; to make modifications that &lt;em&gt;Debian&lt;/em&gt; wants to. But Debian will not accept any Debian-specific permissions.
&lt;p&gt;Debian could of course rename their Rust compiler. Debian has chosen to rename in the past: infamously, a similar policy by Mozilla resulted in Debian distributing Firefox under the name Iceweasel for many years. This is a PR problem for everyone involved, and results in a good deal of technical inconvenience and makework.
&lt;p&gt;&amp;ldquo;Debian could seek approval for changes, and the Rust Foundation would grant that approval quickly&amp;rdquo;. This is unworkable on a practical level - requests for permission do not fit into Debian&amp;rsquo;s workflow, and the resulting delays would be unacceptable. But, more fundamentally, Debian rightly insists that it must have the freedom to make changes that the Foundation do not approve of. (For example, if a future Rust shipped with telemetry features Debian objected to.)
&lt;p&gt;&amp;ldquo;Debian and Rust could compromise&amp;rdquo;. However, Debian is an ideological as well as technological project. The principles I have set out are part of Debian&amp;rsquo;s Foundation Documents - they are core values for Debian. When Debian makes compromises, it does so very slowly and with great deliberation, using its slowest and most heavyweight constitutional governance processes. Debian is not likely to want to engage in such a process for the benefit of one programming language.
&lt;p&gt;&amp;ldquo;Users will get Rust from upstream&amp;rdquo;. This is currently often the case. Right now, Rust is moving very quickly, and by Debian standards is very new. As Rust becomes more widely used, more stable, and more part of the infrastructure of the software world, it will need to become part of standard, stable, reliable, software distributions. That means Debian.
&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;(The consultation was a Google Forms page with a single text field, so the formatting isn&amp;rsquo;t great. I have edited the formatting very lightly to avoid rendering bugs here on my blog.)&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=19151" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:18695</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/18695.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=18695"/>
    <title>derive-deftly is nearing 1.x - call for review/testing</title>
    <published>2024-07-03T18:32:06Z</published>
    <updated>2024-07-03T18:32:57Z</updated>
    <category term="derive-deftly"/>
    <category term="rust"/>
    <category term="derive-adhoc"/>
    <category term="computers"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;p&gt;&lt;a href="https://docs.rs/derive-deftly/latest/derive_deftly/"&gt;&lt;code&gt;derive-deftly&lt;/code&gt;&lt;/a&gt;, the template-based derive-macro facility for Rust, has been a great success.
&lt;p&gt;It&amp;rsquo;s coming up to time to declare a stable 1.x version. If you&amp;rsquo;d like to try it out, and have final comments / observations, now is the time.
&lt;ul&gt;&lt;li&gt;&lt;a href="#introduction-to-derive-deftly"&gt;Introduction to derive-deftly&lt;/a&gt;
&lt;li&gt;&lt;a href="#status"&gt;Status&lt;/a&gt;
&lt;li&gt;&lt;a href="#history"&gt;History&lt;/a&gt;
&lt;li&gt;&lt;a href="#plans---call-for-reviewtesting"&gt;Plans - call for review/testing&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h3&gt;&lt;a name="introduction-to-derive-deftly"&gt;Introduction to derive-deftly&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Have you ever wished that you could that could write a new &lt;code&gt;derive&lt;/code&gt; macro without having to mess with procedural macros?
&lt;p&gt;You can!
&lt;p&gt;&lt;a href="https://docs.rs/derive-deftly/latest/derive_deftly"&gt;&lt;code&gt;derive-deftly&lt;/code&gt;&lt;/a&gt; lets you write a &lt;code&gt;#[derive]&lt;/code&gt; macro, using a template syntax which looks a lot like &lt;code&gt;macro_rules!&lt;/code&gt;:
&lt;pre&gt;&lt;code&gt;use derive_deftly::{define_derive_deftly, Deftly};

define_derive_deftly! {
    ListVariants:

    impl $ttype {
        fn list_variants() -&amp;gt; Vec&amp;lt;&amp;amp;&amp;#39;static str&amp;gt; {
            vec![ $( stringify!( $vname ) , ) ]
        }
    }
}

#[derive(Deftly)]
#[derive_deftly(ListVariants)]
enum Enum {
    UnitVariant,
    StructVariant { a: u8, b: u16 },
    TupleVariant(u8, u16),
}

assert_eq!(
    Enum::list_variants(),
    [&amp;quot;UnitVariant&amp;quot;, &amp;quot;StructVariant&amp;quot;, &amp;quot;TupleVariant&amp;quot;],
);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;&lt;a name="status"&gt;Status&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;derive-deftly has a wide range of features, which can be used to easily write sophisticated and reliable derive macros. We&amp;rsquo;ve been using it in &lt;a href="http://arti.torproject.org/"&gt;Arti&lt;/a&gt;, the Tor Project&amp;rsquo;s reimplementation of Tor in Rust, and we&amp;rsquo;ve found it very useful.
&lt;p&gt;There is comprehensive &lt;a href="https://docs.rs/derive-deftly/latest/derive_deftly/doc_reference/index.html"&gt;reference documentation&lt;/a&gt;, and more discursive &lt;a href="https://diziet.pages.torproject.net/rust-derive-deftly/latest/guide/"&gt;User Guide&lt;/a&gt; for a more gentle introduction. Naturally, everything is fully tested.
&lt;h3&gt;&lt;a name="history"&gt;History&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;derive-deftly started out as a Tor Hackweek project. It used to be called &lt;code&gt;derive-adhoc&lt;/code&gt;. But we renamed it because we found that many of the most interesting use cases were really not very ad-hoc at all.
&lt;p&gt;Over the past months we&amp;rsquo;ve been ticking off our &amp;ldquo;1.0 blocker&amp;rdquo; tickets. We&amp;rsquo;ve taken the opportunity to improve syntax, terminology, and semantics. We hope we have now made the last breaking changes.
&lt;h3&gt;&lt;a name="plans---call-for-reviewtesting"&gt;Plans - call for review/testing&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the near future, we plan to declare version 1.0. After 1.x, we intend to make breaking changes very rarely.
&lt;p&gt;So, right now, we&amp;rsquo;d like last-minute feedback. Are there any wrinkles that need to be sorted out? Please file tickets or MRs &lt;a href="https://gitlab.torproject.org/Diziet/rust-derive-deftly"&gt;on our gitlab&lt;/a&gt;. Ideally, anything which might imply breaking changes would be submitted on or before the 13th of August.
&lt;p&gt;In the medium to long term, we have many ideas for how to make derive-deftly even more convenient, and even more powerful. But we are going to proceed cautiously, because we don&amp;rsquo;t want to introduce bad syntax or bad features, which will require difficult decisions in the future about forward compatibility.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=18695" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:18530</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/18530.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=18530"/>
    <title>What your vote is worth - a back of the envelope calculation</title>
    <published>2024-06-01T09:36:01Z</published>
    <updated>2024-06-01T09:40:46Z</updated>
    <category term="politics"/>
    <dw:security>public</dw:security>
    <dw:reply-count>4</dw:reply-count>
    <content type="html">&lt;p&gt;tl;dr: Your vote really counts!
&lt;p&gt;&lt;em&gt;Each vote&lt;/em&gt; in a UK General Election is worth maybe &amp;pound;100,000 - to you and all your fellow citizens taken together. If you really care about the welfare of &lt;em&gt;everyone&lt;/em&gt; affected by actions of the UK government, then it&amp;rsquo;s worth that to you too.
&lt;ul&gt;&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;
&lt;li&gt;&lt;a href="#a-method-for-back-of-the-envelope-calculation"&gt;A method for back of the envelope calculation&lt;/a&gt;
&lt;li&gt;&lt;a href="#uk-parliament"&gt;UK Parliament&lt;/a&gt;
&lt;li&gt;&lt;a href="#european-parliament"&gt;European Parliament&lt;/a&gt;
&lt;li&gt;&lt;a href="#only-if-you-care-about-other-people-as-much-as-yourself"&gt;Only if you care about other people as much as yourself!&lt;/a&gt;
&lt;li&gt;&lt;a href="#this-is-a-very-rough-analysis"&gt;This is a very rough analysis&lt;/a&gt;
&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h3&gt;&lt;a name="introduction"&gt;Introduction&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It seems a common perception that one vote, in amongst all those millions, doesn&amp;rsquo;t really matter. So maybe it&amp;rsquo;s not worth voting. But, voting is (largely) what determines what the government does - and the government is &lt;em&gt;big&lt;/em&gt;. It&amp;rsquo;s as big as all the people.
&lt;p&gt;If you are the kind of person who cares about what happens to &lt;em&gt;everyone&lt;/em&gt; in your polity and indeed everyone its actions affect, then even your one vote is very important indeed.
&lt;h3&gt;&lt;a name="a-method-for-back-of-the-envelope-calculation"&gt;A method for back of the envelope calculation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It would be nice to give a quantitative estimate. Many things in our society are measured in money, so let&amp;rsquo;s try taking a stab at calculating the money value of your vote.
&lt;p&gt;The argument I&amp;rsquo;m going to make is this: the government (by which I include the legislature), which is selected by our votes, decides how to spend the national budget.
&lt;p&gt;So, basically, I&amp;rsquo;m going to divide the budget, by the electorate.
&lt;h3&gt;&lt;a name="uk-parliament"&gt;UK Parliament&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;UK Parliamentary elections decide not only the House of Commons, but, through that, the government. The upper house, the House of Lords, has very limited influence. So I think it&amp;rsquo;s fair to regard the Parliamentary election as, simply, controlling that budget.
&lt;p&gt;Being lazy, I&amp;rsquo;m going to use Wikipedia data. We have the &lt;a href="https://en.wikipedia.org/wiki/Constituencies_of_the_Parliament_of_the_United_Kingdom"&gt;size of the electorate&lt;/a&gt;, for 2019, 47.6 million. But your influence isn&amp;rsquo;t shared with the whole electorate, only with the other people who also vote. &lt;a href="https://en.wikipedia.org/wiki/Uk_general_elections#21st_century"&gt;Turnout in 2019&lt;/a&gt; was 67.3%. The 2019 budget isn&amp;rsquo;t listed but I&amp;rsquo;ll just average the &lt;a href="https://en.wikipedia.org/wiki/United_Kingdom_budget#List_of_budgets"&gt;2018 and March 2020 figures&lt;/a&gt; &amp;pound;842bn and &amp;pound;873bn, so &amp;pound;857 billion. (Strictly speaking I should add up the budgets for the period of the Parliament, but that seems like a lot of effort.)
&lt;p&gt;There&amp;rsquo;s a discrepancy in the timescale we need to account for. Your vote influences the budgets for several years, depending how long it is until the next election. Taking Wikipedia&amp;rsquo;s &lt;a href="https://en.wikipedia.org/wiki/Uk_general_elections#21st_century"&gt;list of elections this century&lt;/a&gt; there&amp;rsquo;ve been 7 in 24 years. So that&amp;rsquo;s an average of about 3.4y.
&lt;p&gt;So, multiplying it through, we have (&amp;pound;857b * (24 / 7)) / (47.6M * 67.3%), giving a guess at the value of your UK General Election vote:
&lt;p&gt;&amp;pound;92,000.
&lt;h3&gt;&lt;a name="european-parliament"&gt;European Parliament&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;2022 budget for the European Union (&lt;a href="https://en.wikipedia.org/wiki/Budget_of_the_European_Union"&gt;Wikipedia again&lt;/a&gt;) was &amp;euro;170.6 bn.
&lt;p&gt;The last election, in 2019, &lt;a href="https://en.wikipedia.org/wiki/2019_European_Parliament_election"&gt;had a turnout&lt;/a&gt; of 198,352,638. Each EU Parliament lasts 5 years.
&lt;p&gt;The Parliament, however, shares responsibility for the budget with the European Council, which is controlled, ultimately, by national governments. We have to pick a numerical value for the Parliament&amp;rsquo;s share of the influence. Over the past years the Parliament has gradually been more willing to exercise its powers in this area. I&amp;rsquo;m going to arbitrarily call its share 50%.
&lt;p&gt;The calculation, then, is &amp;euro;170.6 bn * 5 * 50% / 198M, giving a guess at the value of your EU Parliamentary Election vote:
&lt;p&gt;&amp;euro;2150.
&lt;p&gt;This much smaller figure reflects simply that the EU doesn&amp;rsquo;t spend very much money, for a polity of its size. (Those stories in the British press giving the impression that the EU is massively wasteful are, simply, lies.)
&lt;p&gt;The interaction of this calculation with the &lt;em&gt;Council&lt;/em&gt;&amp;rsquo;s share of the influence, and with national budgets, is a bit of a question, but given the much smaller amounts involved, it doesn&amp;rsquo;t seem worth thinking about that too hard.
&lt;h3&gt;&lt;a name="only-if-you-care-about-other-people-as-much-as-yourself"&gt;Only if you care about other people as much as yourself!&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;All of this is only true for you if you value and want to help everyone in your society. That includes immigrants, women, unemployed people, disabled people, people who are much poorer or richer than you, etc.
&lt;p&gt;If you think about it in purely personal terms, your vote is hardly worth anything - because while the effect of your vote, overall, is very large, that effect is shared by everyone in your polity. So if you only care about yourself, voting is a total waste of time. The more selfish and xenophobic and racist and so on you are - caring only about people like yourself - the less your vote is worth.
&lt;p&gt;This is why voting is rightly seen as a &lt;strong&gt;civic duty&lt;/strong&gt;. I just spent &amp;pound;30 to courier my EP vote to Den Haag. That only makes sense because I&amp;rsquo;m very willing to spend that &amp;pound;30 to try to improve the spending of the &amp;euro;2000 or so that&amp;rsquo;s my share of the EU budget.
&lt;h3&gt;&lt;a name="this-is-a-very-rough-analysis"&gt;This is a very rough analysis&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;These calculations neglect a lot of very important things: politics isn&amp;rsquo;t just about the allocation of resources. It&amp;rsquo;s also about values, and bad politics can seriously harm people.
&lt;p&gt;Arguably many of those effects of your vote, are much more important than just how the budget is set and spent.
&lt;p&gt;It would be interesting to see an attempt at a similar analysis but for taking into account life and death questions like hate crime, traffic violence, healthcare, refugees&amp;rsquo; welfare, and so on. I&amp;rsquo;m not sure how to approach that. Maybe some real social scientists have done so? References welcome.
&lt;p&gt;Also, even on its own terms, this analysis is very rough and ready. We haven&amp;rsquo;t modelled the ability of the government to change its tax rates; perhaps we should be multiplying GDP (or some other better measure) by 90% percentile total tax rate amongst &amp;ldquo;countries like this one&amp;rdquo;. The amount of influence that can be wielded by one vote is probably nonlinear in the size of the political faction, but IDK in which direction. In unfair voting systems like the UK&amp;rsquo;s, some people&amp;rsquo;s votes are worth &lt;em&gt;much&lt;/em&gt; more than others. In a very marginal constituency, which is a target seat, your vote might be worth tens of millions. In a safe seat, it might &amp;ldquo;only&amp;rdquo; be worth a few thousand. And in practical terms you don&amp;rsquo;t get to choose precisely the policies you want; you have to pick a party, which is sometimes very much a question of the lesser evil.
&lt;p&gt;So, there is much I haven&amp;rsquo;t modelled. But the key point stands:
&lt;h3&gt;&lt;a name="conclusion"&gt;Conclusion&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Although your vote is diluted by everyone else&amp;rsquo;s votes, together, we control the government, which affects us all. So if you care about the whole of society, the big numbers in the divisor, and the numerator, cancel out.
&lt;p&gt;You can think of your vote as controlling one citizen&amp;rsquo;s worth of government activity.
&lt;address&gt;edited 2024-06-01 09:40 Z to fix a grammar botch&lt;/address&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=18530" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:18394</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/18394.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=18394"/>
    <title>Why we’ve voted No to CfD for Derril Water solar farm</title>
    <published>2024-04-09T21:37:51Z</published>
    <updated>2024-04-09T21:38:10Z</updated>
    <category term="derril water"/>
    <category term="climate emergency"/>
    <category term="politics"/>
    <dw:security>public</dw:security>
    <dw:reply-count>2</dw:reply-count>
    <content type="html">&lt;p&gt;&lt;span style='white-space: nowrap;'&gt;&lt;a href='https://ceb.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://ceb.dreamwidth.org/'&gt;&lt;b&gt;ceb&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; and I are members of the &lt;a href="https://rippleenergy.com/our-projects/derril-water-solar-park"&gt;Derril Water Solar Park cooperative&lt;/a&gt;.
&lt;p&gt;We were recently invited to vote on whether the coop should bid for a Contract for Difference, in a government green electricity auction.
&lt;p&gt;We&amp;rsquo;ve voted No.
&lt;ul&gt;&lt;li&gt;&lt;a href="#green-electricity-from-your-mainstream-supplier-is-a-lie"&gt;&amp;ldquo;Green electricity&amp;rdquo; from your mainstream supplier is a lie&lt;/a&gt;
&lt;li&gt;&lt;a href="#ripple"&gt;Ripple&lt;/a&gt;
&lt;li&gt;&lt;a href="#contracts-for-difference"&gt;Contracts for Difference&lt;/a&gt;
&lt;li&gt;&lt;a href="#ripple-and-cfd"&gt;Ripple and CfD&lt;/a&gt;
&lt;li&gt;&lt;a href="#voting-no"&gt;Voting No&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;
&lt;h3&gt;&lt;a name="green-electricity-from-your-mainstream-supplier-is-a-lie"&gt;&amp;ldquo;Green electricity&amp;rdquo; from your mainstream supplier is a lie&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For a while &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://ceb.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://ceb.dreamwidth.org/'&gt;&lt;b&gt;ceb&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; and I have wanted to contribute directly to green energy provision. This isn&amp;rsquo;t really possible in the mainstream consumer electricy market.
&lt;p&gt;Mainstream electricity suppliers&amp;rsquo; &amp;ldquo;100% green energy&amp;rdquo; tariffs &lt;a href="https://www.cse.org.uk/advice/green-electricity-tariffs/"&gt;are pure greenwashing&lt;/a&gt;. In a capitalist boondoogle, they basically &amp;ldquo;divvy up&amp;rdquo; the electricity so that customers on the (typically more expensive) &amp;ldquo;green&amp;rdquo; tariff &amp;ldquo;get&amp;rdquo; the green electricity, and the other customers &amp;ldquo;get&amp;rdquo; whatever is left. (Of course the electricity is actually all mixed up by the National Grid.) There are fewer people signed up for these tariffs than there is green power generated, so this basically means signing up for a &amp;ldquo;green&amp;rdquo; tariff has no effect whatsoever, other than giving evil people more money.
&lt;h3&gt;&lt;a name="ripple"&gt;Ripple&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;About a year ago we heard about Ripple. The structure is a little complicated, but the basic upshot is:
&lt;p&gt;Ripple promote and manage renewable energy schemes. The schemes themselves are each an individual company; the company is largely owned by a co-operative. The co-op is owned by consumers of electricity in the UK., To stop the co-operative being an purely financial investment scheme, shares ownership is limited according to your electricity usage. The electricity is be sold on the open market, and the profits are used to offset members&amp;rsquo; electricity bills. (One gotcha from all of this is that for this to work your electricity billing provider has to be signed up with Ripple, but ours, Octopus, is.)
&lt;p&gt;It seemed to us that this was a way for us to directly cause (and pay for!) the actual generation of green electricity.
&lt;p&gt;So, we bought shares in one these co-operatives: we are co-owners of the &lt;a href="https://www.derrilwater-solarfarm.co.uk/the-project/planning-application/"&gt;Derril Water Solar Farm&lt;/a&gt;. We signed up for the maximum: funding generating capacity corresponding to 120% of our current electricity usage. We paid a little over &amp;pound;5000 for our shares.
&lt;h3&gt;&lt;a name="contracts-for-difference"&gt;Contracts for Difference&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The UK has a renewable energy subsidy scheme, which goes by the name of &lt;a href="https://www.gov.uk/government/collections/contracts-for-difference"&gt;Contracts for Difference&lt;/a&gt;. The idea is that a renewable energy generation company bids in advance, saying that they&amp;rsquo;ll sell their electricity at Y price, for the duration of the contract (15 years in the current round). The lowest bids win. All the electricity from the participating infrastructure is sold on the open market, but if the market price is low the government makes up the difference, and if the price is high, the government takes the winnings.
&lt;p&gt;This is supposedly good for giving a stable investment environment, since the price the developer is going to get now doesn&amp;rsquo;t depends on the electricity market over the next 15 years. The CfD system is supposed to encourage development, so you can only apply before you&amp;rsquo;ve commissioned your generation infrastructure.
&lt;h3&gt;&lt;a name="ripple-and-cfd"&gt;Ripple and CfD&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ripple recently invited us to agree that the Derril Water co-operative should bid in the current round of CfDs.
&lt;p&gt;If this goes ahead, and we are one of the auction&amp;rsquo;s winners, the result would be that, instead of selling our electricity at the market price, we&amp;rsquo;ll sell it at the fixed CfD price.
&lt;p&gt;This would mean that our return on our investment (which show up as savings on our electricity bills) would be decoupled from market electricity prices, and be much more predictable.
&lt;p&gt;They can&amp;rsquo;t tell us the price they&amp;rsquo;d want to bid at, and future electricity prices are rather hard to predict, but it&amp;rsquo;s clear from the accompanying projections that they think we&amp;rsquo;d be better off on average with a CfD.
&lt;p&gt;The documentation is very full of financial projections and graphs; other factors aren&amp;rsquo;t really discussed in any detail.
&lt;p&gt;The rules of the co-op didn&amp;rsquo;t require them to hold a vote, but very sensibly, for such a fundamental change in the model, they decided to treat it roughly the same way as for a rules change: they&amp;rsquo;re hoping to get 75% Yes votes.
&lt;h3&gt;&lt;a name="voting-no"&gt;Voting No&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The reason we&amp;rsquo;re in this co-op at all is because we want to directly fund renewable electricity.
&lt;p&gt;Participating in the CfD auction would involve us competing with capitalist energy companies for government subsidies. Subsidies which are supposed to encourage the provision of green electricity.
&lt;p&gt;It seems to us that participating in this auction would remove most of the difference between what we hoped to do by investing in Derril Water, and just participating in the normal consumer electricity market.
&lt;p&gt;In particular, if we do win in the auction, that&amp;rsquo;s probably directly removing the funding and investment support model for other, market-investor-funded, projects.
&lt;p&gt;In other words, our buying into Derril Water ceases to be an &lt;em&gt;additional&lt;/em&gt; green energy project, changing (in its minor way) the UK&amp;rsquo;s electricity mix. It becomes a financial transaction much more tenously connected (if connected at all) to helping mitigate the climate emergency.
&lt;p&gt;So our conclusion was that we must vote against.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=18394" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:18122</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/18122.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=18122"/>
    <title>How to use Rust on Debian (and Ubuntu, etc.)</title>
    <published>2024-03-21T20:05:46Z</published>
    <updated>2024-03-21T21:47:04Z</updated>
    <category term="debian"/>
    <category term="rust"/>
    <category term="nailing-cargo"/>
    <category term="computers"/>
    <dw:security>public</dw:security>
    <dw:reply-count>4</dw:reply-count>
    <content type="html">&lt;p&gt;tl;dr: Don&amp;rsquo;t just &lt;code&gt;apt install rustc cargo&lt;/code&gt;. Either do that &lt;strong&gt;and make sure to use only Rust libraries from your distro&lt;/strong&gt; (with the tiresome config runes below); or, just use &lt;a href="https://www.rust-lang.org/learn/get-started"&gt;rustup&lt;/a&gt;.
&lt;ul&gt;&lt;li&gt;&lt;a href="#dont-do-the-obvious-thing-its-never-what-you-want"&gt;Don&amp;rsquo;t do the obvious thing; it&amp;rsquo;s never what you want&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#q.-download-and-run-whatever-code-from-the-internet"&gt;Q. Download and run whatever code from the internet?&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#option-1-wtf-no-i-dont-want-curlbash"&gt;Option 1: WTF, no I don&amp;rsquo;t want &lt;code&gt;curl|bash&lt;/code&gt;&lt;/a&gt;
&lt;li&gt;&lt;a href="#option-2-biting-the-curlbash-bullet"&gt;Option 2: Biting the &lt;code&gt;curl|bash&lt;/code&gt; bullet&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#privilege-separation"&gt;Privilege separation&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;li&gt;&lt;a href="#omg-what-a-mess"&gt;OMG what a mess&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;p&gt;
&lt;h3&gt;&lt;a name="dont-do-the-obvious-thing-its-never-what-you-want"&gt;Don&amp;rsquo;t do the obvious thing; it&amp;rsquo;s never what you want&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Debian ships a Rust compiler, and a large number of Rust libraries.
&lt;p&gt;But if you just do things the obvious &amp;ldquo;default&amp;rdquo; way, with &lt;code&gt;apt install rustc cargo&lt;/code&gt;, you will end up using Debian&amp;rsquo;s &lt;em&gt;compiler&lt;/em&gt; but &lt;em&gt;upstream&lt;/em&gt; libraries, directly and uncurated from crates.io.
&lt;p&gt;This is not what you want. There are about two reasonable things to do, depending on your preferences.
&lt;h4&gt;&lt;a name="q.-download-and-run-whatever-code-from-the-internet"&gt;Q. Download and run whatever code from the internet?&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The key question is this:
&lt;p&gt;Are you comfortable downloading code, directly from hundreds of upstream Rust package maintainers, and running it ?
&lt;p&gt;That&amp;rsquo;s what &lt;code&gt;cargo&lt;/code&gt; does. It&amp;rsquo;s one of the main things it&amp;rsquo;s &lt;em&gt;for&lt;/em&gt;. Debian&amp;rsquo;s &lt;code&gt;cargo&lt;/code&gt; behaves, in this respect, just like upstream&amp;rsquo;s. Let me say that again:
&lt;p&gt;&lt;strong&gt;Debian&amp;rsquo;s cargo promiscuously downloads code from crates.io&lt;/strong&gt; just like upstream cargo.
&lt;p&gt;So if you use Debian&amp;rsquo;s cargo in the most obvious way, you are &lt;em&gt;still&lt;/em&gt; downloading and running all those random libraries. The only thing you&amp;rsquo;re &lt;em&gt;avoiding&lt;/em&gt; downloading is the Rust compiler itself, which is precisely the part that is most carefully maintained, and of least concern.
&lt;p&gt;Debian&amp;rsquo;s cargo can even download from crates.io when you&amp;rsquo;re building official Debian source packages written in Rust: if you run &lt;code&gt;dpkg-buildpackage&lt;/code&gt;, the downloading is suppressed; but a plain &lt;code&gt;cargo build&lt;/code&gt; will try to obtain and use dependencies from the upstream ecosystem. (&amp;ldquo;Happily&amp;rdquo;, if you do this, it&amp;rsquo;s quite likely to bail out early due to version mismatches, before actually downloading anything.)
&lt;h3&gt;&lt;a name="option-1-wtf-no-i-dont-want-curlbash"&gt;Option 1: WTF, no I don&amp;rsquo;t want &lt;code&gt;curl|bash&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;OK, but then you must limit yourself to libraries available &lt;em&gt;within&lt;/em&gt; Debian. Each Debian release provides a curated set. It may or may not be sufficient for your needs. Many capable programs can be written using the packages in Debian.
&lt;p&gt;But any &lt;em&gt;upstream&lt;/em&gt; Rust project that you encounter is likely to be a pain to get working, unless their maintainers specifically intend to support this. (This is fairly rare, and the Rust tooling doesn&amp;rsquo;t make it easy.)
&lt;p&gt;To go with this plan, &lt;code&gt;apt install rustc cargo&lt;/code&gt; and &lt;strong&gt;put this in your configuration&lt;/strong&gt;, in &lt;code&gt;$HOME/.cargo/config.toml&lt;/code&gt;:
&lt;pre&gt;&lt;code&gt;[source.debian-packages]
directory = &amp;quot;/usr/share/cargo/registry&amp;quot;
[source.crates-io]
replace-with = &amp;quot;debian-packages&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This causes cargo to look in &lt;code&gt;/usr/share&lt;/code&gt; for dependencies, rather than downloading them from crates.io. You must then install the &lt;code&gt;librust-FOO-dev&lt;/code&gt; packages for each of your dependencies, with &lt;code&gt;apt&lt;/code&gt;.
&lt;p&gt;This will allow you to write your own program in Rust, and build it using &lt;code&gt;cargo build&lt;/code&gt;.
&lt;h3&gt;&lt;a name="option-2-biting-the-curlbash-bullet"&gt;Option 2: Biting the &lt;code&gt;curl|bash&lt;/code&gt; bullet&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you want to build software that isn&amp;rsquo;t specifically targeted at Debian&amp;rsquo;s Rust you will probably &lt;em&gt;need&lt;/em&gt; to use packages from crates.io, &lt;em&gt;not&lt;/em&gt; from Debian.
&lt;p&gt;If you&amp;rsquo;re doing to do that, there is little point not using &lt;a href="https://www.rust-lang.org/learn/get-started"&gt;rustup&lt;/a&gt; to get the latest compiler. rustup&amp;rsquo;s install rune is alarming, but cargo will be doing exactly the same kind of thing, only worse (because it trusts many more people) and more hidden.
&lt;p&gt;So in this case: &lt;em&gt;do&lt;/em&gt; run the &lt;a href="https://www.rust-lang.org/learn/get-started"&gt;&lt;code&gt;curl|bash&lt;/code&gt; install rune&lt;/a&gt;.
&lt;p&gt;Hopefully the Rust project you are trying to build have shipped a &lt;code&gt;Cargo.lock&lt;/code&gt;; that contains hashes of all the dependencies that &lt;em&gt;they&lt;/em&gt; last used and tested. If you run &lt;code&gt;cargo build --locked&lt;/code&gt;, cargo will &lt;em&gt;only&lt;/em&gt; use those versions, which are hopefully OK.
&lt;p&gt;And you can run &lt;code&gt;cargo audit&lt;/code&gt; to see if there are any reported vulnerabilities or problems. But you&amp;rsquo;ll have to bootstrap this with &lt;code&gt;cargo install --locked cargo-audit&lt;/code&gt;; cargo-audit is from the &lt;a href="https://rustsec.org/"&gt;RUSTSEC&lt;/a&gt; folks who do care about these kind of things, so hopefully running their code (and their dependencies) is fine. Note the &lt;code&gt;--locked&lt;/code&gt; which is needed because &lt;a href="https://github.com/rust-lang/cargo/issues/7169"&gt;cargo&amp;rsquo;s default behaviour is wrong&lt;/a&gt;.
&lt;h4&gt;&lt;a name="privilege-separation"&gt;Privilege separation&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This approach is rather alarming. For my personal use, I wrote a privsep tool which allows me to run all this upstream Rust code as a separate user.
&lt;p&gt;That tool is &lt;a href="https://diziet.dreamwidth.org/8848.html"&gt;nailing-cargo&lt;/a&gt;. It&amp;rsquo;s not particularly well productised, or tested, but it does work for at least one person besides me. You may wish to try it out, or consider alternative arrangements. &lt;a href="https://salsa.debian.org/iwj/nailing-cargo"&gt;Bug reports and patches welcome&lt;/a&gt;.
&lt;h3&gt;&lt;a name="omg-what-a-mess"&gt;OMG what a mess&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Indeed. There are large number of technical and social factors at play.
&lt;p&gt;cargo itself is deeply troubling, both in principle, and in detail. I often find myself severely disappointed with its maintainers&amp;rsquo; decisions. In mitigation, much of the wider Rust upstream community &lt;em&gt;does&lt;/em&gt; takes this kind of thing very seriously, and often makes good choices. &lt;a href="https://rustsec.org/"&gt;RUSTSEC&lt;/a&gt; is one of the results.
&lt;p&gt;Debian&amp;rsquo;s technical arrangements for Rust packaging are quite dysfunctional, too: IMO the scheme is based on fundamentally wrong design principles. But, the Debian Rust packaging team is dynamic, constantly working the update treadmills; and the team is generally welcoming and helpful.
&lt;p&gt;Sadly last time I explored the possibility, the Debian Rust Team didn&amp;rsquo;t have the appetite for more fundamental changes to the &lt;a href="https://salsa.debian.org/rust-team/debcargo-conf/-/blob/master/README.rst"&gt;workflow&lt;/a&gt; (including, for example, &lt;a href="https://diziet.dreamwidth.org/10559.html"&gt;changes to dependency version handling&lt;/a&gt;). Significant improvements to upstream cargo&amp;rsquo;s approach seem unlikely, too; we can only hope that eventually someone might manage to supplant it.

&lt;address&gt;edited 2024-03-21 21:49 to add a cut tag&lt;/address&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=18122" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:17698</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/17698.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=17698"/>
    <title>UPS, the Useless Parcel Service; VAT and fees</title>
    <published>2024-02-02T00:37:45Z</published>
    <updated>2024-02-02T00:38:13Z</updated>
    <category term="personal"/>
    <category term="legal"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;p&gt;I recently had the most astonishingly bad experience with UPS, the courier company. They severely damaged my parcels, and were very bad about UK import VAT, ultimately ending up harassing me on autopilot.
&lt;p&gt;The only thing that got their attention was my draft Particulars of Claim for intended legal action.
&lt;p&gt;Surprisingly, I got them to admit in writing that the &amp;ldquo;disbursement fee&amp;rdquo; they charge recipients alongside the actual VAT, is just something they made up with no legal basis.
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;p&gt;
&lt;h3&gt;&lt;a name="what-happened"&gt;What happened&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Autumn last year I ordered some furniture from a company in Germany. This was to be shipped by them to me by courier. The supplier chose UPS.
&lt;p&gt;UPS misrouted one of the three parcels to Denmark. When everything arrived, it had been sat on by elephants. The supplier had to replace most of it, with considerable inconvenience and delay to me, and of course a loss to the supplier.
&lt;p&gt;But this post isn&amp;rsquo;t mostly about that. This post is about VAT. You see, import VAT was due, because of fucking Brexit.
&lt;p&gt;UPS made a &lt;em&gt;complete hash&lt;/em&gt; of collecting that VAT. Their computers can&amp;rsquo;t issue coherent documents, their email helpdesk is completely useless, and their automated debt collection systems run along uninfluenced by any external input.
&lt;p&gt;The crazy, including legal threats and escalating late payment fees, continued even after I paid the VAT discrepancy (which I did despite them not yet having provided any coherent calculation for it).
&lt;p&gt;This kind of behaviour is a very small and mild version of the kind of things British Gas did to Lisa Ferguson, who eventually &lt;a href="https://www.pinsentmasons.com/out-law/news/debt-collection-can-be-harassment-british-gas-ruling-sends-warning-to-all-suppliers"&gt;won substantial damages for harassment, plus &amp;pound;10K of costs&lt;/a&gt;.
&lt;p&gt;Having tried asking nicely, and sending stiff letters, I too threatened litigation.
&lt;p&gt;I would have actually started a court claim, but it would have included a claim under the Protection from Harassment Act. Those have to be filed under the &amp;ldquo;Part 8 procedure&amp;rdquo;, which involves sending &lt;em&gt;all of the written evidence&lt;/em&gt; you&amp;rsquo;re going to use &lt;em&gt;along with the claim form&lt;/em&gt;. Collating all that would be a good deal of work, especially since UPS and ControlAccount didn&amp;rsquo;t engage with me at all, so I had no idea which things they might actually dispute. So I decided that before issuing proceedings, I&amp;rsquo;d send them a copy of my draft Particulars of Claim, along with an offer to settle if they would pay me a modest sum and stop being evil robots at me.
&lt;p&gt;Rather than me typing the whole tale in again, you can read the full gory details in &lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2024/ups-particulars-redacted.pdf"&gt;the PDF of my draft Particulars of Claim&lt;/a&gt;. (I&amp;rsquo;ve redacted the reference numbers).
&lt;h3&gt;&lt;a name="outcome"&gt;Outcome&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The draft Particulars finally got their attention. UPS sent me an offer: they agreed to pay me &amp;pound;50, in full and final settlement. That was close enough to my offer that I accepted it. I mostly wanted them to stop, and they do seem to have done so. And I&amp;rsquo;ve received the &amp;pound;50.
&lt;h4&gt;&lt;a name="vat-calculation"&gt;VAT calculation&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;They also finally included an actual explanation of the VAT calculation. It&amp;rsquo;s absurd, but it&amp;rsquo;s not UPS&amp;rsquo;s absurd:
&lt;blockquote&gt;&lt;p&gt;The clearance was entered initially with estimated import charges of &amp;pound;400.03, consisting of &amp;pound;387.83 VAT, and &amp;pound;12.20 disbursement fee. This original entry regrettably did not include the freight cost for calculating the VAT, and as such when submitted for final entry the VAT value was adjusted to include this and an amended invoice was issued for an additional &amp;pound;39.84.
&lt;p&gt;HMRC calculate the amount against which VAT is raised using the value of goods, insurance and freight, however they also may apply a VAT adjustment figure.
&lt;p&gt;The VAT Adjustment is based on many factors (Incidental costs in regards to a shipment), which includes charge for currency conversion if the invoice does not list values in Sterling, but the main is due to the inland freight from airport of destination to the final delivery point, as this charge varies, for example, from EMA to Edinburgh would be &amp;pound;150, from EMA to Derby would be &amp;pound;1, so each year UPS must supply HMRC with all values incurred for entry build up and they give an average which UPS have to use on the entry build up as the VAT Adjustment.
&lt;p&gt;The correct calculation for the import charges is therefore as follows:
&lt;p&gt;Goods value divided by exchange rate 2,489.53 EUR / 1.1683 = 2,130.89 GBP
&lt;p&gt;Duty: Goods value plus freight (%) 2,130.89 GBP + 5% = 2,237.43 GBP. That total times the duty rate. X 0 % = 0 GBP
&lt;p&gt;VAT: Goods value plus freight (100%) 2,130.89 GBP + 0 = 2,130.89 GBP
&lt;p&gt;That total plus duty and VAT adjustment 2,130.89 GBP + 0 GBP + 7.49 GBP = 2,348.08 GBP. That total times 20% VAT = 427.67 GBP
&lt;p&gt;As detailed above we must confirm that the final VAT charges applied to the shipment were correct, and that no refund of this is therefore due.
&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This looks very like HMRC-originated nonsense. If only they had put it on the original bills! It&amp;rsquo;s completely ridiculous that it took four months and near-litigation to obtain it.
&lt;h4&gt;&lt;a name="disbursement-fee"&gt;&amp;ldquo;Disbursement fee&amp;rdquo;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;One more thing. UPS billed me a &amp;pound;12 &amp;ldquo;disbursement fee&amp;rdquo;.
&lt;p&gt;When you import something, there&amp;rsquo;s often tax to pay. The courier company pays that to the government, and the consignee pays it to the courier. Usually the courier demands it before final delivery, since otherwise they end up having to chase it as a debt.
&lt;p&gt;It is common for parcel companies to add a random fee of their own. As I note in my Particulars, there isn&amp;rsquo;t any legal basis for this.
&lt;p&gt;In my own offer of settlement I proposed that UPS should:
&lt;blockquote&gt;&lt;p&gt;State under what principle of English law (such as, what enactment or principle of Common Law), you levy the &amp;ldquo;disbursement fee&amp;rdquo; (or refund it).
&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;To my surprise they actually responded to this in their own settlement letter. (They didn&amp;rsquo;t, for example, mention the harassment at all.) They said (emphasis mine):
&lt;blockquote&gt;&lt;p&gt;A disbursement fee is a fee for amounts paid or processed on behalf of a client. It is an established category of charge used by legal firms, amongst other companies, for billing of various ancillary costs which may be incurred in completion of service. &lt;strong&gt;Disbursement fees are not covered by a specific law&lt;/strong&gt;, nor are they legally prohibited.
&lt;p&gt;Regarding UPS&amp;rsquo; disbursement fee this is an administrative charge levied for the use of UPS&amp;rsquo; deferment account to prepay import charges for clearance through CDS. This charge would therefore be billed to the party that is responsible for the import charges, normally the consignee or receiver of the shipment in question. The disbursement fee as applied is legitimate, and as you have stated is a commonly used and recognised charge throughout the courier industry, and I can confirm that this was charged correctly in this instance.
&lt;/p&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;On UPS&amp;rsquo;s analysis, they can just make up whatever fee they like. That is clearly not right (and I don&amp;rsquo;t even need to refer to consumer protection law, which would also make it obviously unlawful).
&lt;p&gt;And, that everyone does it doesn&amp;rsquo;t make it lawful. There are &lt;em&gt;so many&lt;/em&gt; things that are ubiquitous but unlawful, especially nowadays when much of the legal system - especially consumer protection regulators - has been underfunded to beyond the point of collapse.
&lt;p&gt;Next time this comes up I might have a go at getting the fee back. (Obviously I&amp;rsquo;ll have to pay it first, to get my parcel.)
&lt;h5&gt;&lt;a name="parcelforce-and-royal-mail"&gt;ParcelForce and Royal Mail&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;I think this analysis doesn&amp;rsquo;t apply to ParcelForce and (probably) Royal Mail. I looked into this in 2009, and I found that Parcelforce had been given the ability to write their own private laws: &amp;ldquo;Schemes&amp;rdquo; made under section 89 of the Postal Services Act 2000.
&lt;p&gt;This is obviously ridiculous but I think it was the law in 2009. I doubt the intervening governments have fixed it.
&lt;h4&gt;&lt;a name="furniture"&gt;Furniture&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Oh, yes, the actual furniture. The replacements arrived intact and are great :-).&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=17698" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:17579</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/17579.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=17579"/>
    <title>Don’t use apt-get source; use dgit</title>
    <published>2023-12-04T15:10:52Z</published>
    <updated>2023-12-04T15:12:25Z</updated>
    <category term="computers"/>
    <category term="dgit"/>
    <category term="debian"/>
    <dw:security>public</dw:security>
    <dw:reply-count>1</dw:reply-count>
    <content type="html">&lt;p&gt;tl;dr:
&lt;p&gt;If you are a Debian user who knows git, &lt;strong&gt;don&amp;rsquo;t work with Debian source packages&lt;/strong&gt;. Don&amp;rsquo;t use &lt;code&gt;apt source&lt;/code&gt;, or &lt;code&gt;dpkg-source&lt;/code&gt;. Instead, &lt;strong&gt;use &lt;a href="https://manpages.debian.org/stable/dgit/dgit-user.7.en.html"&gt;dgit&lt;/a&gt; and work in git&lt;/strong&gt;.
&lt;p&gt;Also, &lt;strong&gt;don&amp;rsquo;t&lt;/strong&gt; use: &amp;ldquo;VCS&amp;rdquo; links on official Debian web pages, &lt;code&gt;debcheckout&lt;/code&gt;, or Debian&amp;rsquo;s (semi-)official gitlab, Salsa. These are suitable for Debian experts only; for most people they &lt;a href="https://diziet.dreamwidth.org/9556.html"&gt;can be beartraps&lt;/a&gt;. Instead, use &lt;a href="https://manpages.debian.org/stable/dgit/dgit-user.7.en.html"&gt;dgit&lt;/a&gt;.
&lt;ul&gt;&lt;li&gt;&lt;a href="#struggling-with-debian-source-packages"&gt;Struggling with Debian source packages?&lt;/a&gt;
&lt;li&gt;&lt;a href="#just-use-dgit"&gt;Just use dgit&lt;/a&gt;
&lt;li&gt;&lt;a href="#objections"&gt;Objections&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="#but-i-dont-want-to-learn-yet-another-tool"&gt;But I don&amp;rsquo;t want to learn &lt;em&gt;yet another&lt;/em&gt; tool&lt;/a&gt;
&lt;li&gt;&lt;a href="#shouldnt-i-be-using-official-debian-git-repos"&gt;Shouldn&amp;rsquo;t I be using &amp;ldquo;official&amp;rdquo; Debian git repos?&lt;/a&gt;
&lt;li&gt;&lt;a href="#gosh-is-debian-really-this-bad"&gt;Gosh, is Debian really this bad?&lt;/a&gt;
&lt;li&gt;&lt;a href="#im-a-debian-maintainer.-you-tell-me-dgit-is-something-totally-different"&gt;I&amp;rsquo;m a Debian maintainer. You tell &lt;em&gt;me&lt;/em&gt; dgit is something totally different!&lt;/a&gt;
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;&amp;gt;
&lt;h3&gt;&lt;a name="struggling-with-debian-source-packages"&gt;Struggling with Debian source packages?&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A friend of mine recently asked for help on IRC. They&amp;rsquo;re an experienced Debian administrator and user, and were trying to: make a change to a Debian package; build and install and run binary packages from it; and record that change for their future self, and their colleagues. They ended up trying to comprehend quilt.
&lt;p&gt;&lt;a href="https://manpages.debian.org/bookworm/quilt/quilt.1.en.html"&gt;quilt&lt;/a&gt; is an ancient utility for managing sets of source code patches, from well before the era of modern version control. It has many strange behaviours and footguns. Debian&amp;rsquo;s ancient and obsolete tarballs-and-patches &lt;a href="https://manpages.debian.org/bookworm/dpkg-dev/dpkg-source.1.en.html"&gt;source package format&lt;/a&gt; (which I designed the initial version of in 1993) nowadays uses quilt, at least for most packages.
&lt;p&gt;You don&amp;rsquo;t want to deal with any of this nonsense. You don&amp;rsquo;t want to learn quilt, and suffer its misbehaviours. You don&amp;rsquo;t want to learn about Debian source packages and wrestle dpkg-source.
&lt;p&gt;Happily, you don&amp;rsquo;t need to.
&lt;h3&gt;&lt;a name="just-use-dgit"&gt;Just use dgit&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One of dgit&amp;rsquo;s main objectives is to minimise the amount of Debian craziness you need to learn. dgit aims to empower you to make changes to the software you&amp;rsquo;re running, conveniently and with a minimum of fuss.
&lt;p&gt;You can use dgit to get the source code to a Debian package, as a git tree, with &lt;code&gt;dgit clone&lt;/code&gt; (and &lt;code&gt;dgit fetch&lt;/code&gt;). The git tree can be made into a binary package directly.
&lt;p&gt;The only things you really need to know are:
&lt;ol type="1"&gt;&lt;li&gt;&lt;p&gt;By default dgit fetches from Debian unstable, the main work-in-progress branch. You may want something like &lt;code&gt;dgit clone PACKAGE bookworm,-security&lt;/code&gt; (yes, with a comma).

&lt;li&gt;&lt;p&gt;You probably want to edit &lt;code&gt;debian/changelog&lt;/code&gt; to make your packages have a different version number.

&lt;li&gt;&lt;p&gt;To build binaries, run &lt;code&gt;dpkg-buildpackage -uc -b&lt;/code&gt;.

&lt;li&gt;&lt;p&gt;Debian package builds are often disastrously messsy: builds might modify source files; and the official &lt;code&gt;debian/rules clean&lt;/code&gt; can be inadequate, or crazy. Always commit before building, and use &lt;code&gt;git clean&lt;/code&gt; and &lt;code&gt;git reset --hard&lt;/code&gt; instead of running clean rules from the package.

&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Don&amp;rsquo;t try to make a Debian source package. (Don&amp;rsquo;t read the &lt;code&gt;dpkg-source&lt;/code&gt; manual!) Instead, to preserve and share your work, use the git branch.
&lt;p&gt;&lt;code&gt;dgit pull&lt;/code&gt; or &lt;code&gt;dgit fetch&lt;/code&gt; can be used to get updates.
&lt;p&gt;There is a more comprehensive tutorial, with example runes, in the &lt;a href="https://manpages.debian.org/stable/dgit/dgit-user.7.en.html"&gt;dgit-user(7)&lt;/a&gt; manpage. (There is of course &lt;a href="https://manpages.debian.org/bookworm/dgit/dgit.1.en.html"&gt;complete reference documentation&lt;/a&gt;, but you don&amp;rsquo;t need to bother reading it.)
&lt;h3&gt;&lt;a name="objections"&gt;Objections&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;a name="but-i-dont-want-to-learn-yet-another-tool"&gt;But I don&amp;rsquo;t want to learn &lt;em&gt;yet another&lt;/em&gt; tool&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;One of dgit&amp;rsquo;s main goals is to save people from learning things you don&amp;rsquo;t need to. It aims to be straightforward, convenient, and (so far as Debian permits) unsurprising.
&lt;p&gt;So: don&amp;rsquo;t &lt;em&gt;learn&lt;/em&gt; dgit. Just run it and it will be fine :-).
&lt;h4&gt;&lt;a name="shouldnt-i-be-using-official-debian-git-repos"&gt;Shouldn&amp;rsquo;t I be using &amp;ldquo;official&amp;rdquo; Debian git repos?&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Absolutely not.&lt;/strong&gt;
&lt;p&gt;Unless you are a Debian expert, these can be terrible beartraps. One possible outcome is that you might build an apparently working program &lt;em&gt;but without the security patches&lt;/em&gt;. Yikes!
&lt;p&gt;I discussed this in more detail in 2021 in &lt;a href="https://diziet.dreamwidth.org/9556.html"&gt;another blog post plugging dgit&lt;/a&gt;.
&lt;h4&gt;&lt;a name="gosh-is-debian-really-this-bad"&gt;Gosh, is Debian really this bad?&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Yes. On behalf of the Debian Project, I apologise.
&lt;p&gt;Debian is a very conservative institution. Change usually comes very slowly. (And when rapid or radical change has been forced through, the results haven&amp;rsquo;t always been pretty, either technically or socially.)
&lt;p&gt;Sadly this means that sometimes much needed change can take a very long time, if it happens at all. But this tendency also provides the stability and reliability that people have come to rely on Debian for.
&lt;h4&gt;&lt;a name="im-a-debian-maintainer.-you-tell-me-dgit-is-something-totally-different"&gt;I&amp;rsquo;m a Debian maintainer. You tell &lt;em&gt;me&lt;/em&gt; dgit is something totally different!&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;dgit is, in fact, a general bidirectional gateway between the Debian archive and git.
&lt;p&gt;So yes, dgit is also a tool for Debian uploaders. You should use it to do your uploads, whenever you can. It&amp;rsquo;s more convenient and more reliable than &lt;code&gt;git-buildpackage&lt;/code&gt; and &lt;code&gt;dput&lt;/code&gt; runes, and produces better output for users. You too can start to forget how to deal with source packages!
&lt;p&gt;A full treatment of this is beyond the scope of this blog post.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=17579" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:17079</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/17079.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=17079"/>
    <title>Hacking my filter coffee machine</title>
    <published>2023-11-26T14:27:48Z</published>
    <updated>2023-11-26T14:59:00Z</updated>
    <category term="engineering"/>
    <dw:security>public</dw:security>
    <dw:reply-count>2</dw:reply-count>
    <content type="html">&lt;p&gt;I hacked my coffee machine to let me turn it on from upstairs in bed :-). Read on for explanation, circuit diagrams, 3D models, firmware source code, and pictures.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#background-the-morphy-richards-filter-coffee-machine"&gt;Background: the Morphy Richards filter coffee machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#planning"&gt;Planning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#inside-the-morphy-richards-filter-coffee-machine"&gt;Inside the Morphy Richards filter coffee machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#unexpected-electrical-hazard"&gt;Unexpected electrical hazard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design-approach"&gt;Design approach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation---hardware"&gt;Implementation - hardware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation---software"&gt;Implementation - software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#results"&gt;Results&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#epilogue"&gt;Epilogue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#bonus-pictures"&gt;Bonus pictures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Background: the Morphy Richards filter coffee machine&lt;/h3&gt;
&lt;p&gt;I have a Morphy Richards filter coffee machine. It makes very good coffee. But the display and firmware are quite annoying:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;After it has finished making the coffee, it will keep the coffee warm using its hotplate, but only for 25 minutes. If you want to make a batch and drink it over the course of the morning that’s far too short.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has a timer function. But it only has a 12 hour clock! You can’t retire upstairs on a Friday night, having programmed the coffee machine to make you coffee at a suitable post-lie-in time. If you try, you are greeted with apparently-inexplicably-cold coffee.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The buttons and UI are very confusing. For example, if it’s just sitting there keeping the coffee warm, and you pour the last, you want to turn it off. So you press the power button. Then the display lights up as if you’ve just turned it on! (The power LED is in the power button, which your finger is on.) If you know this you can get used to it, but it can confuse guests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, I’m lazy and wanted to be able to cause coffee to exist from upstairs in bed, without having to make a special trip down just to turn the machine on.&lt;/p&gt;
&lt;h3&gt;Planning&lt;/h3&gt;
&lt;p&gt;My original feeling was “I can’t be bothered dealing with the coffee machine innards” so I thought I would make a mechanical contraption to physically press the coffee machine’s “on” button.&lt;/p&gt;
&lt;p&gt;I could have my contraption press the button to turn the machine on (timed, or triggered remotely), and then periodically in pairs to reset the 25-minute keep-warm timer.&lt;/p&gt;
&lt;p&gt;But a friend pointed me at &lt;a href="https://andybradford.dev/2021/11/23/hacking-some-smarts-into-a-basic-coffee-machine/"&gt;a blog post by Andy Bradford&lt;/a&gt;, where Andy recounts modifying his coffee machine, adding an ESP8266 and connecting it to his MQTT-based Home Assistant setup.&lt;/p&gt;
&lt;p&gt;I looked at the pictures and they looked very similar to my machine. I decided to take a look inside.&lt;/p&gt;
&lt;h3&gt;Inside the Morphy Richards filter coffee machine&lt;/h3&gt;
&lt;p&gt;My coffee machine seemed to be very similar to Andy’s. His disassembly report was very helpful. Inside I found the high-voltage parts with the heating elements, and the front panel with the display and buttons.&lt;/p&gt;
&lt;p&gt;I spent a while poking about, masuring things, and so on.&lt;/p&gt;
&lt;h3&gt;Unexpected electrical hazard&lt;/h3&gt;
&lt;p&gt;At one point I wanted to use my storage oscilloscope to capture the duration and amplitude of the “beep” signal. I needed to connect the ’scope ground to the UI board’s ground plane, but then when I switched the coffee machine on at the wall socket, it tripped the house’s RCD.&lt;/p&gt;
&lt;p&gt;It turns out that the “low voltage” UI board is coupled to the mains. In my setting, there’s an offset of about 8V between the UI board ground plane, and true earth. (In my house the neutral is about 2-3V away from true earth.)&lt;/p&gt;
&lt;p&gt;This alarmed me rather. To me, this means that my modifications needed to still properly electrically isolate everything connected to the UI board from anything external to the coffee machine’s housing.&lt;/p&gt;
&lt;p&gt;In Andy’s design, I think the internal UI board ground plane is directly brought out to an external USB-A connector. This means that if there were a neutral fault, the USB-A connector would be at live potential, possibly creating an electrocution or fire hazard. I made a comment in Andy Bradford’s blog, reporting this issue, but it doesn’t seem to have appeared. This is all quite alarming. I hope Andy is OK!&lt;/p&gt;
&lt;h3&gt;Design approach&lt;/h3&gt;
&lt;p&gt;I don’t have an MQTT setup at home, or an installation of Home Assistant. I didn’t feel like adding a lot of complicated software to my life, if I could avoid it. Nor did I feel like writing a web UI myself. I’ve done that before, but I’m lazy and in this case my requirements were quite modest.&lt;/p&gt;
&lt;p&gt;Also, the need for electrical isolation would further complicate any attempt to do something sophisticated (that could, for example, sense the state of the coffee machine).&lt;/p&gt;
&lt;p&gt;I already had a &lt;a href="https://tasmota.github.io/docs/"&gt;Tasmota&lt;/a&gt;-based cloud-free smart plug, which controls the fairy lights on &lt;a href="https://diziet.dreamwidth.org/tag/engineering"&gt;our gazebo&lt;/a&gt;. We just operate that through its web UI. So, I decided I would add a small and stupid microcontroller. The microcontroller would be powered via a smart plug and an off-the-shelf USB power supply.&lt;/p&gt;
&lt;p&gt;The microcontroller would have no inputs. It would simply simulate an “on” button press once at startup, and thereafter two presses every 24 minutes. After the 4th double press the microcontroller would stop, leaving the coffee machine to time out itself, after a total period of about 2h.&lt;/p&gt;
&lt;h3&gt;Implementation - hardware&lt;/h3&gt;
&lt;p&gt;I used a DigiSpark board with an ATTiny85. One of the GPIOs is connected to an optoisolator, whose output transistor is wired across the UI board’s “on” button.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/diagrams/doc00104220231126002704.pdf"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/doc00104220231126002704.pdf.jpg" alt="circuit diagram;" /&gt;&lt;/a&gt; &lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/diagrams/doc00104120231126002650.pdf"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/doc00104120231126002650.pdf.jpg" alt="board layout diagram;" /&gt;&lt;/a&gt; (click for diagram scans as pdfs).&lt;/p&gt;
&lt;p&gt;The DigiSpark has just a USB tongue, which is very wobbly in a normal USB socket. I designed a &lt;a href="https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=reprap-play.git;a=blob;f=digispark-with-cable.scad;hb=HEAD"&gt;3D printed case&lt;/a&gt; which also had an approximation of the rest of the USB A plug. The plug is out of spec; our printer won’t go fine enough - and anyway, the shield is supposed to be metal, not fragile plastic. But it fit in the USB PSU I was using, satisfactorily if a bit stiffly, and also into the connector for programming via my laptop.&lt;/p&gt;
&lt;p&gt;Inside the coffee machine, there’s the boundary between the original, coupled to mains, UI board, and the isolated low voltage of the microcontroller. I used a reasonably substantial cable to bring out the low voltage connection, past all the other hazardous innards, to make sure it stays isolated.&lt;/p&gt;
&lt;p&gt;I added a “drain power supply” resistor on another of the GPIOs. This is enabled, with a draw of about 30mA, when the microcontroller is soon going to “off”/“on” cycle the coffee machine. That reduces the risk that the user will turn off the smart plug, and turn off the machine, but that the microcontroller turns the coffee machine back on again using the remaining power from USB PSU. Empirically in my setup it reduces the time from “smart plug off” to “microcontroller stops” from about 2-3s to more like 1s.&lt;/p&gt;
&lt;h4&gt;Optoisolator board (inside coffee machine) pictures&lt;/h4&gt;
&lt;p&gt;(Click through for full size images.)&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/pictures/IMG_20231019_231220.jpg"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/IMG_20231019_231220.jpg" alt="optoisolator board, front;" /&gt;&lt;/a&gt; &lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/pictures/IMG_20231019_231449.jpg"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/IMG_20231019_231449.jpg" alt="optoisolator board, rear;" /&gt;&lt;/a&gt; &lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/pictures/IMG_20231019_234657.jpg"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/IMG_20231019_234657.jpg" alt="optoisolator board, fitted." /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Microcontroller board (in USB-plug-ish housing) pictures&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/pictures/IMG_20231020_002349.jpg"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/IMG_20231020_002349.jpg" alt="microcontroller board, component side;" /&gt;&lt;/a&gt; &lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/pictures/IMG_20231020_003453.jpg"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/IMG_20231020_003453.jpg" alt="microcontroller board, wiring side, part fitted;" /&gt;&lt;/a&gt; &lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/pictures/IMG_20231020_010125.jpg"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/IMG_20231020_010125.jpg" alt="microcontroller in USB-plug-ish housing." /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Implementation - software&lt;/h3&gt;
&lt;p&gt;I originally used the Arduino IDE, writing my program in C. &lt;a href="https://diziet.dreamwidth.org/16771.html"&gt;I had a bad time with that and rewrote it in Rust&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://salsa.debian.org/iwj/coffee-machine-keepalive-firmware"&gt;firmware is in a repository on Debian’s gitlab&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Results&lt;/h3&gt;
&lt;p&gt;I can now cause the coffee to start, from my phone. It can be programmed more than 12h in advance. And it stays warm until we’ve drunk it.&lt;/p&gt;
&lt;h4&gt;UI is worse&lt;/h4&gt;
&lt;p&gt;There’s one aspect of the original Morphy Richards machine that I haven’t improved: the user interface is still poor. Indeed, it’s now even worse:&lt;/p&gt;
&lt;p&gt;To turn the machine on, you probably want to turn on the smart plug instead. Unhappily, the power button for that is invisible in its installed location.&lt;/p&gt;
&lt;p&gt;In particular, in the usual case, if you want to turn it off, you should ideally turn off &lt;em&gt;both&lt;/em&gt; the smart plug (which can be done with the button on it) &lt;em&gt;and&lt;/em&gt; the coffee machine itself. If you forget to turn off the smart plug, the machine can end up being turned on, very briefly, a handful of times, over the next hour or two.&lt;/p&gt;
&lt;h3&gt;Epilogue&lt;/h3&gt;
&lt;p&gt;We had used the new features a handful of times when one morning the coffee machine just wouldn’t make coffee. The UI showed it turning on, but it wouldn’t get hot, so no coffee. I thought “oh no, I’ve broken it!”&lt;/p&gt;
&lt;p&gt;But, on investigation, I found that the machine’s heating element was open circuit (ie, completely broken). I didn’t mess with that part. So, hooray! Not my fault. Probably, just being inverted a number of times and generally lightly jostled, had precipitated a latent fault. The machine was a number of years old.&lt;/p&gt;
&lt;p&gt;Happily I found a replacement, identical, machine, online. I’ve transplanted my modification and now it all works well.&lt;/p&gt;
&lt;h3&gt;Bonus pictures&lt;/h3&gt;
&lt;p&gt;(Click through for full size images.)&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/pictures/IMG_20231019_231127.jpg"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/IMG_20231019_231127.jpg" alt="probing the innards;" /&gt;&lt;/a&gt; &lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/pictures/IMG_20231019_235007.jpg"&gt;&lt;img src="https://www.chiark.greenend.org.uk/~ijackson/2023/coffee-machine-keepalive/thumbnails/IMG_20231019_235007.jpg" alt="machine base showing new cable route." /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;address&gt;edited 2023-11-26 14:59 UTC in an attempt to fix TOC links&lt;/address&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=17079" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:16771</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/16771.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=16771"/>
    <title>DigiSpark (ATTiny85) - Arduino, C, Rust, build systems</title>
    <published>2023-10-22T16:02:09Z</published>
    <updated>2023-10-22T16:04:48Z</updated>
    <category term="computers"/>
    <category term="rust"/>
    <dw:security>public</dw:security>
    <dw:reply-count>5</dw:reply-count>
    <content type="html">&lt;p&gt;Recently I completed a small project, including an embedded microcontroller. For me, using the popular Arduino IDE, and C, was a mistake. The experience with Rust was better, but still very exciting, and not in a good way.&lt;/p&gt;
&lt;p&gt;Here follows the rant.&lt;/p&gt;


&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#arduino-ide"&gt;Arduino IDE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#writing-c-again"&gt;Writing C again&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#rust-on-the-digispark"&gt;Rust on the DigiSpark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#riir-rewrite-it-in-rust"&gt;RIIR (Rewrite It In Rust)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#an-offer-of-help"&gt;An offer of help&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusions"&gt;Conclusions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In a recent project (I’ll write about the purpose, and the hardware in another post) I chose to use a &lt;a href="http://digistump.com/products/1"&gt;DigiSpark&lt;/a&gt; board. This is a small board with a USB-A tongue (but not a proper plug), and an &lt;a href="https://www.microchip.com/en-us/product/ATtiny85"&gt;ATTiny85&lt;/a&gt; microcontroller, This chip has 8 pins and is quite small really, but it was plenty for my application. By choosing something popular, I hoped for convenient hardware, and an uncomplicated experience.&lt;/p&gt;
&lt;p&gt;Convenient hardware, I got.&lt;/p&gt;
&lt;h3&gt;Arduino IDE&lt;/h3&gt;
&lt;p&gt;The usual way to program these boards is via an IDE. I thought I’d go with the flow and try that. I knew these were closely related to actual Arduinos and saw that the IDE package &lt;a href="https://packages.debian.org/bookworm/arduino"&gt;&lt;code&gt;arduino&lt;/code&gt;&lt;/a&gt; was in Debian.&lt;/p&gt;
&lt;p&gt;But it turns out that the Debian package’s version doesn’t support the DigiSpark. (AFAICT from the list it offered me, I’m not sure it supports &lt;em&gt;any&lt;/em&gt; ATTiny85 board.) Also, disturbingly, its “board manager” seemed to be offering to “install” board support, suggesting it would download “stuff” from the internet and run it. That wouldn’t be acceptable for my main laptop.&lt;/p&gt;
&lt;p&gt;I didn’t expect to be doing much programming or debugging, and the project didn’t have significant security requirements: the chip, in my circuit, has only a very narrow ability do anything to the real world, and no network connection of any kind. So I thought it would be tolerable to do the project on my low-security “video laptop”. That’s the machine where I’m prepared to say “yes” to installing random software off the internet.&lt;/p&gt;
&lt;p&gt;So I went to the &lt;a href="https://www.arduino.cc/en/software/"&gt;upstream Arduino site&lt;/a&gt; and downloaded a tarball containing the Arduino IDE. After unpacking that in &lt;code&gt;/opt&lt;/code&gt; it ran and produced a pointy-clicky IDE, as expected. I had already found &lt;a href="https://startingelectronics.org/tutorials/arduino/digispark/digispark-linux-setup/"&gt;a 3rd-party tutorial&lt;/a&gt; saying I needed to add a magic URL (from the DigiSpark’s vendor) in the preferences. That indeed allowed it to download a whole pile of stuff. Compilers, bootloader clients, god knows what.&lt;/p&gt;
&lt;p&gt;However, my tiny test program didn’t make it to the board. Half-buried in a too-small window was an error message about the board’s bootloader (“Micronucleus”) being too new.&lt;/p&gt;
&lt;p&gt;The boards I had came pre-flashed with micronucleus 2.2. Which is hardly new, But even so the official Arduino IDE (or maybe the DigiSpark’s board package?) still contains an old version. So now we have all the downsides of &lt;code&gt;curl|bash&lt;/code&gt;-ware, but we’re lacking the “it’s up to date” and “it just works” upsides.&lt;/p&gt;
&lt;p&gt;Further digging found some &lt;a href="https://digistump.com/board/index.php/topic,1834.msg13109.html#msg13109"&gt;random forum posts&lt;/a&gt; which suggested simply downloading &lt;a href="https://github.com/micronucleus/micronucleus"&gt;a newer micronucleus&lt;/a&gt; and manually stuffing it into the right place: one overwrites a specific file, in the middle the heaps of stuff that the Arduino IDE’s board support downloader squirrels away in your home directory. (In my case, the home directory of the untrusted shared user on the video laptop,)&lt;/p&gt;
&lt;p&gt;So, “whatever”. I did that. And it worked!&lt;/p&gt;
&lt;p&gt;Having demo’d my ability to run code on the board, I set about writing my program.&lt;/p&gt;
&lt;h3&gt;Writing C again&lt;/h3&gt;
&lt;p&gt;The programming language offered via the Arduino IDE is C.&lt;/p&gt;
&lt;p&gt;It’s been a little while since I started a new thing in C. After having spent so much of the last several years writing Rust. C’s primitiveness quickly started to grate, and the program couldn’t easily be as DRY as I wanted (Don’t Repeat Yourself, see &lt;a href="https://arxiv.org/abs/1210.0530"&gt;Wilson et al, 2012&lt;/a&gt;, §4, p.6). But, I carried on; after all, this was going to be quite a small job.&lt;/p&gt;
&lt;p&gt;Soon enough I had a program that looked right and compiled.&lt;/p&gt;
&lt;p&gt;Before testing it in circuit, I wanted to do some QA. So I wrote a simulator harness that &lt;code&gt;#include&lt;/code&gt;d my Arduino source file, and provided imitations of the few Arduino library calls my program used. As an side advantage, I could build and run the simulation on my main machine, in my normal development environment (Emacs, &lt;code&gt;make&lt;/code&gt;, etc.). The simulator runs confirmed the correct behaviour. (Perhaps there would have been some more faithful simulation tool, but the Arduino IDE didn’t seem to offer it, and I wasn’t inclined to go further down that kind of path.)&lt;/p&gt;
&lt;p&gt;So I got the video laptop out, and used the Arduino IDE to flash the program. It didn’t run properly. It hung almost immediately. Some very ad-hoc debugging via led-blinking (like printf debugging, only much worse) convinced me that my problem was as follows:&lt;/p&gt;
&lt;p&gt;Arduino C has 16-bit ints. My test harness was on my 64-bit Linux machine. C was autoconverting things (when building for the micrcocontroller). The way the Arduino IDE ran the compiler didn’t pass the warning options necessary to spot narrowing implicit conversions. Those warnings aren’t the default in C in general &lt;del&gt;because C compilers hate us all&lt;/del&gt; for compatibility reasons.&lt;/p&gt;
&lt;p&gt;I don’t know why those warnings are not the default in the Arduino IDE, but my guess is that they didn’t want to bother poor novice programmers with messages from the compiler explaining how their program is quite possibly wrong. After all, users don’t like error messages so we shouldn’t report errors. And novice programmers are especially fazed by error messages so it’s better to just let them struggle themselves with the arcane mysteries of undefined behaviour in C?&lt;/p&gt;
&lt;p&gt;The Arduino IDE does offer a dropdown for “compiler warnings”. The default is None. Setting it to All didn’t produce anything about my integer overflow bugs. And, the output was very hard to find anyway because the “log” window has a constant stream of strange messages from &lt;code&gt;javax.jmdns&lt;/code&gt;, with hex DNS packet dumps. WTF.&lt;/p&gt;
&lt;p&gt;Other things that were vexing about the Arduino IDE: it has fairly fixed notions (which don’t seem to be documented) about how your files and directories ought to be laid out, and magical machinery for finding things you put “nearby” its “sketch” (as it calls them) and sticking them in its ear, causing lossage. It has a tendency to become confused if you edit files under its feet (e.g. with &lt;code&gt;git checkout&lt;/code&gt;). It wasn’t really very suited to a workflow where principal development occurs elsewhere.&lt;/p&gt;
&lt;p&gt;And, important settings such as the project’s clock speed, or even the target board, or &lt;em&gt;the compiler warning settings to use&lt;/em&gt; weren’t stored in the project directory along with the actual code. I didn’t look too hard, but I presume they must be in a dotfile somewhere. This is madness.&lt;/p&gt;
&lt;p&gt;Apparently there is an Arduino CLI too. But I was already quite exasperated, and I didn’t like the idea of going so far off the beaten path, when the whole point of using all this was to stay with popular tooling and share fate with others. (How do these others cope? I have no idea.)&lt;/p&gt;
&lt;p&gt;As for the integer overflow bug:&lt;/p&gt;
&lt;p&gt;I didn’t seriously consider trying to figure out how to control in detail the C compiler options passed by the Arduino IDE. (Perhaps this is &lt;a href="https://forum.arduino.cc/t/compiler-options/468759"&gt;possible, but not really documented&lt;/a&gt;?) I did consider trying to run a cross-compiler myself from the command line, with appropriate warning options, but that would have involved providing (or stubbing, again) the Arduino/DigiSpark libraries (and bugs could easily lurk at that interface).&lt;/p&gt;
&lt;p&gt;Instead, I thought, “if only I had written the thing in Rust”. But that wasn’t possible, was it? Does Rust even support this board?&lt;/p&gt;
&lt;h3&gt;Rust on the DigiSpark&lt;/h3&gt;
&lt;p&gt;I did a cursory web search and found a very useful &lt;a href="https://dylan-garrett.com/blog/rust-digispark-attiny/"&gt;blog post by Dylan Garrett&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This encouraged me to think it might be a workable strategy. I looked at the instructions there. It seemed like I could run them via the &lt;a href="https://diziet.dreamwidth.org/tag/nailing-cargo"&gt;privsep arrangement&lt;/a&gt; I use to protect myself when developing using upstream cargo packages from &lt;code&gt;crates.io&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I got surprisingly far surprisingly quickly. It did, rather startlingly, cause my &lt;code&gt;rustup&lt;/code&gt; to download a random recent Nightly Rust, but I have six of those already for other Reasons. Very quickly I got the “trinket” LED blink example, referenced by Dylan’s blog post, to compile. Manually copying the file to the video laptop allowed me to run the previously-downloaded micronucleus executable and successfully run the blink example on my board!&lt;/p&gt;
&lt;p&gt;I thought a more principled approach to the bootloader client might allow a more convenient workflow. I found the &lt;a href="https://github.com/micronucleus/micronucleus"&gt;upstream Micronucleus&lt;/a&gt; git releases and tags, and had a look over its source code, release dates, etc. It seemed plausible, so I compiled v2.6 from source. That was a success: now I could build and install a Rust program onto my board, from the command line, on my main machine. No more pratting about with the video laptop.&lt;/p&gt;
&lt;p&gt;I had got further, more quickly, with Rust, than with the Arduino IDE, and the outcome and workflow was superior.&lt;/p&gt;
&lt;p&gt;So, basking in my success, I copied the directory containing the example into my own project, renamed it, and adjusted the &lt;code&gt;path&lt;/code&gt; references.&lt;/p&gt;
&lt;p&gt;That didn’t work. Now it didn’t build. Even after I copied about &lt;code&gt;.cargo/config.toml&lt;/code&gt; and &lt;code&gt;rust-toolchain.toml&lt;/code&gt; it didn’t build, producing a variety of exciting messages, depending what precisely I tried. I don’t have detailed logs of my flailing: the instructions say to build it by &lt;code&gt;cd&lt;/code&gt;’ing to the subdirectory, and, given that what I was trying to do was to &lt;em&gt;not&lt;/em&gt; follow those instructions, it didn’t seem sensible to try to prepare a proper repro so I could file a ticket. I wasn’t optimistic about investigating it more deeply myself: I have some experience of fighting cargo, and it’s not usually fun. Looking at some of the build control files, things seemed quite complicated.&lt;/p&gt;
&lt;p&gt;Additionally, not all of the crates are on &lt;code&gt;crates.io&lt;/code&gt;. I have no idea why not. So, I would need to supply “local” copies of them anyway. I decided to just &lt;a href="https://diziet.dreamwidth.org/14666.html"&gt;&lt;code&gt;git subtree add&lt;/code&gt;&lt;/a&gt; the &lt;a href="https://github.com/Rahix/avr-hal/issues"&gt;&lt;code&gt;avr-hal&lt;/code&gt; git tree&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;(That seemed better than the approach taken by the avr-hal project’s &lt;a href="https://github.com/Rahix/avr-hal-template"&gt;cargo template&lt;/a&gt;, since that template involve a cargo dependency on a foreign &lt;code&gt;git&lt;/code&gt; repository. Perhaps it would be possible to turn them into &lt;code&gt;path&lt;/code&gt; dependencies, but given that I had evidence of file-location-sensitive behaviour, which I didn’t feel like I wanted to spend time investigating, using that seems like it would possibly have invited more trouble. Also, I don’t like package templates very much. They’re a form of clone-and-hack: you end up stuck with whatever bugs or oddities exist in the version of the template which was current when you started.)&lt;/p&gt;
&lt;p&gt;Since I couldn’t get things to build outside &lt;code&gt;avr-hal&lt;/code&gt;, I edited the example, within &lt;code&gt;avr-hal&lt;/code&gt;, to refer to my (one) &lt;code&gt;program.rs&lt;/code&gt; file &lt;em&gt;outside&lt;/em&gt; &lt;code&gt;avr-hal&lt;/code&gt;, with a &lt;a href="https://salsa.debian.org/iwj/coffee-machine-keepalive-firmware/-/blob/2aec3263053b7ec2a9451b536101fd4def764eca/avr-hal/examples/trinket/src/bin/trinket-blink.rs#L10"&gt;&lt;code&gt;#[path]&lt;/code&gt; instruction&lt;/a&gt;. That’s not pretty, but it worked.&lt;/p&gt;
&lt;p&gt;I also had to write a &lt;a href="https://salsa.debian.org/iwj/coffee-machine-keepalive-firmware/-/blob/2aec3263053b7ec2a9451b536101fd4def764eca/in-avr-hal"&gt;nasty shell script&lt;/a&gt; to work around the lack of good support in my &lt;a href="https://diziet.dreamwidth.org/8848.html"&gt;&lt;code&gt;nailing-cargo&lt;/code&gt;&lt;/a&gt; privsep tool for builds where &lt;code&gt;cargo&lt;/code&gt; must be invoked in a deep subdirectory, and/or &lt;code&gt;Cargo.lock&lt;/code&gt; isn’t where it expects, and/or the &lt;code&gt;target&lt;/code&gt; directory containing build products is in a weird place. It also has to filter the output from &lt;code&gt;cargo&lt;/code&gt; to adjust the pathnames in the error messages. Otherwise, running both &lt;code&gt;cd A; cargo build&lt;/code&gt; and &lt;code&gt;cd B; cargo build&lt;/code&gt; from a &lt;code&gt;Makefile&lt;/code&gt; produces confusing sets of error messages, some of which contain filenames relative to &lt;code&gt;A&lt;/code&gt; and some relative to &lt;code&gt;B&lt;/code&gt;, making it impossible for my Emacs to reliably find the right file.&lt;/p&gt;
&lt;h3&gt;RIIR (Rewrite It In Rust)&lt;/h3&gt;
&lt;p&gt;Having got my build tooling sorted out I could go back to my actual program.&lt;/p&gt;
&lt;p&gt;I translated the main program, and the simulator, from C to Rust, more or less line-by-line. I made the Rust version of the simulator produce the same output format as the C one. That let me check that the two programs had the same (simulated) behaviour. Which they did (after fixing a few glitches in the simulator log formatting).&lt;/p&gt;
&lt;p&gt;Emboldened, I flashed the Rust version of my program to the DigiSpark. It worked right away!&lt;/p&gt;
&lt;p&gt;RIIR had caused the bug to vanish. Of course, to rewrite the program in Rust, and get it to compile, it was necessary to be careful about the types of all the various integers, so that’s not so surprising. Indeed, it was the point. I was then able to refactor the program to be a bit more natural and DRY, and improve some internal interfaces. Rust’s greater power, compared to C, made those cleanups easier, so making them worthwhile.&lt;/p&gt;
&lt;p&gt;However, when doing real-world testing I found a weird problem: my timings were off. Measured, the real program was too fast by a factor of slightly more than 2. A bit of searching (and searching my memory) revealed the cause: I was using a board template for an Adafruit Trinket. The Trinket has a clock speed of 8MHz. But the DigiSpark runs at 16.5MHz. (This is discussed in a &lt;a href="https://github.com/SpenceKonde/ATTinyCore/issues/349"&gt;ticket&lt;/a&gt; against one of the C/C++ libraries supporting the ATTiny85 chip.)&lt;/p&gt;
&lt;p&gt;The Arduino IDE had offered me a choice of clock speeds. I have no idea how that dropdown menu took effect; I suspect it was adding prelude code to adjust the clock prescaler. But my attempts to mess with the CPU clock prescaler register by hand at the start of my Rust program didn’t bear fruit.&lt;/p&gt;
&lt;p&gt;So instead, I adopted a bodge: since my code has (for code structure reasons, amongst others) only one place where it dealt with the underlying hardware’s notion of time, I simply changed my &lt;code&gt;delay&lt;/code&gt; function to &lt;a href="https://salsa.debian.org/iwj/coffee-machine-keepalive-firmware/-/blob/2aec3263053b7ec2a9451b536101fd4def764eca/avr-hal/examples/trinket/src/bin/trinket-blink.rs#L22"&gt;adjust the passed-in delay values&lt;/a&gt;, compensating for the wrong clock speed.&lt;/p&gt;
&lt;p&gt;There was probably a more principled way. For example I could have (re)based my work on either of the two &lt;a href="https://github.com/Rahix/avr-hal/pull/367"&gt;unmerged&lt;/a&gt; &lt;a href="https://github.com/Rahix/avr-hal/pull/401"&gt;open&lt;/a&gt; MRs which added proper support for the DigiSpark board, rather than abusing the Adafruit Trinket definition. But, having a nearly-working setup, and an explanation for the behaviour, I preferred the narrower fix to reopening any cans of worms.&lt;/p&gt;
&lt;h3&gt;An offer of help&lt;/h3&gt;
&lt;p&gt;As will be obvious from this posting, I’m not an expert in dev tools for embedded systems. Far from it. This area seems like quite a deep swamp, and I’m probably not the person to help drain it. (Frankly, much of the improvement work ought to be done, and paid for, by hardware vendors.)&lt;/p&gt;
&lt;p&gt;But, as a full Member of the Debian Project, I have considerable gatekeeping authority there. I also have much experience of software packaging, build systems, and release management. If anyone wants to try to improve the situation with embedded tooling in Debian, and is willing to do the actual packaging work. I would be happy to advise, and to review and sponsor your contributions.&lt;/p&gt;
&lt;p&gt;An obvious candidate: it seems to me that &lt;code&gt;micronucleus&lt;/code&gt; could easily be in Debian. Possibly a DigiSpark board definition could be provided to go with the &lt;code&gt;arduino&lt;/code&gt; package.&lt;/p&gt;
&lt;p&gt;Unfortunately, IMO Debian’s Rust packaging tooling and workflows are very poor, and the first of my &lt;a href="https://diziet.dreamwidth.org/10559.html"&gt;suggestions for improvement&lt;/a&gt; wasn’t well received. So if you need help with improving Rust packages in Debian, please talk to the &lt;a href="https://lists.debian.org/debian-rust/"&gt;Debian Rust Team&lt;/a&gt; yourself.&lt;/p&gt;
&lt;h3&gt;Conclusions&lt;/h3&gt;
&lt;p&gt;Embedded programming is still rather a mess and probably always will be.&lt;/p&gt;
&lt;p&gt;Embedded build systems can be bizarre. Documentation is scant. You’re often expected to download “board support packages” full of mystery binaries, from the board vendor (or others).&lt;/p&gt;
&lt;p&gt;Dev tooling is maddening, especially if aimed at novice programmers. You want version control? Hermetic tracking of your project’s build and install configuration? Actually to be told by the compiler when you write obvious bugs? You’re way off the beaten track.&lt;/p&gt;
&lt;p&gt;As ever, Free Software is under-resourced and the maintainers are often busy, or (reasonably) have other things to do with their lives.&lt;/p&gt;
&lt;h4&gt;All is not lost&lt;/h4&gt;
&lt;p&gt;Rust can be a significantly better bet than C for embedded software:&lt;/p&gt;
&lt;p&gt;The Rust compiler will catch a good proportion of programming errors, and an experienced Rust programmer can arrange (by suitable internal architecture) to catch nearly all of them. When writing for a chip in the middle of some circuit, where debugging involves staring an LED or a multimeter, that’s precisely what you want.&lt;/p&gt;
&lt;p&gt;Rust embedded dev tooling was, in this case, considerably better. Still quite chaotic and strange, and less mature, perhaps. But: significantly fewer mystery downloads, and significantly less crazy deviations from the language’s normal build system. Overall, less bad software supply chain integrity.&lt;/p&gt;
&lt;p&gt;The ATTiny85 chip, and the DigiSpark board, served my hardware needs very well. (More about the hardware aspects of this project in a future posting.)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=16771" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:16518</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/16518.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=16518"/>
    <title>Conferences take note: the pandemic is not over</title>
    <published>2023-08-31T22:22:56Z</published>
    <updated>2023-08-31T23:59:03Z</updated>
    <category term="covid"/>
    <category term="debian"/>
    <category term="bicon"/>
    <category term="diversity"/>
    <category term="politics"/>
    <dw:security>public</dw:security>
    <dw:reply-count>6</dw:reply-count>
    <content type="html">&lt;p&gt;Many people seem to be pretending that the pandemic is over. It isn’t. People are still getting Covid, becoming sick, and even in some cases becoming disabled. People’s plans are still being disrupted. Vulnerable people are still hiding.&lt;/p&gt;
&lt;p&gt;Conference organisers: please make robust Covid policies, publish them early, and enforce them. And, clearly set expectations for your attendees.&lt;/p&gt;
&lt;p&gt;Attendees: please don’t be the superspreader.&lt;/p&gt;
&lt;p&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Two conferences&lt;/h3&gt;
&lt;p&gt;This year I have attended a number of in-person events.&lt;/p&gt;
&lt;p&gt;For &lt;a href="https://www.conversation2023.org.uk/"&gt;Eastercon&lt;/a&gt; I chose to participate online, remotely. This turns out to have been a very good decision. &lt;strong&gt;At least a quarter&lt;/strong&gt; of attendees got Covid.&lt;/p&gt;
&lt;p&gt;At &lt;a href="https://2023.bicon.org.uk"&gt;BiCon&lt;/a&gt; we had about 300 attendees. I’m not aware of any Covid cases.&lt;/p&gt;
&lt;p&gt;Part of the difference between the two may have been in the policies. &lt;a href="https://2023.bicon.org.uk/Covid-19-policy/"&gt;BiCon’s policy&lt;/a&gt; was rather more robust. Unlike &lt;a href="https://www.conversation2023.org.uk/policies/Covid-policy/"&gt;Eastercon’s&lt;/a&gt; it had a much better refund policy for people who got Covid and therefore shouldn’t come; also BiCon asked attendees to actually show evidence of a negative test. Another part of the difference will have been the venue. The NTU buildings we used at BiCon were modern and well ventilated.&lt;/p&gt;
&lt;p&gt;But, I think the biggest difference was attendees' attitudes. BiCon attendees are disproportionately likely (compared to society at large) to have long term medical conditions. And the cultural norms are to value and protect those people. Conversely, in my experience, a larger proportion of Eastercon attendees don’t always have the same level of consideration. I don’t want to give details, but I have reliable reports of quite reprehensible behaviour by some attendees - even members of the convention volunteer staff.&lt;/p&gt;
&lt;h3&gt;Policies&lt;/h3&gt;
&lt;p&gt;Your conference should IMO &lt;em&gt;at the very least&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Require everyone to show evidence of a negative test, on arrival.&lt;/li&gt;
&lt;li&gt;Have a good refund policy that allows an attendee who would be a risk to others, to cancel without penalty.&lt;/li&gt;
&lt;li&gt;Require everyone to provide proof of vaccination (or medical exemption).&lt;/li&gt;
&lt;li&gt;Clearly state that a negative LFT is not an “all clear”&lt;/li&gt;
&lt;li&gt;Instruct people not to attend, or to isolate if already on-site, if:
&lt;ul&gt;
&lt;li&gt;they have new symptoms of respiratory illness&lt;/li&gt;
&lt;li&gt;they are a contact of known a positive case; &lt;strong&gt;or&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;they have any other reason to suspect they’ll be bringing Covid to the event.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rules should be published very early, so that people can see them, and decide if they want to go, before they have to book anything.&lt;/p&gt;
&lt;h4&gt;Don’t “recommend” that people don’t spread disease&lt;/h4&gt;
&lt;p&gt;Most of the things that attendees can do to about Covid primarily protect others, rather than themselves.&lt;/p&gt;
&lt;p&gt;Making those things “recommendations” or “advice” is grossly unfair. You’re setting up an &lt;a href="https://siderea.dreamwidth.org/1209794.html"&gt;arsehole filter&lt;/a&gt;: nice people will want to protect others, but less public spirited people will tell themselves it’s only a recommendation.&lt;/p&gt;
&lt;p&gt;Make the rules mandatory.&lt;/p&gt;
&lt;h4&gt;But won’t we be driving people away ?&lt;/h4&gt;
&lt;p&gt;If you don’t have a robust Covid policy, you are already driving people away.&lt;/p&gt;
&lt;p&gt;And the people who won’t come because of reasonable measures like I’ve asked for above, are dickheads. You don’t want them putting your other attendees at risk. And probably they’re annoying in other ways too.&lt;/p&gt;
&lt;h4&gt;Example of something that is not OK&lt;/h4&gt;
&lt;p&gt;Yesterday (2023-08-30 13:44 UTC), less than two weeks before the conference, Debconf 23’s Covid policy still looked like you see below.&lt;/p&gt;
&lt;p&gt;Today there is a &lt;a href="https://debconf23.debconf.org/about/covid19/"&gt;policy&lt;/a&gt;, but it is still weak.&lt;/p&gt;
&lt;p&gt;&lt;img width="1735" height="1092" style="width: 50%; height: 31.5%" src="https://www.chiark.greenend.org.uk/~ijackson/2023/debconf23-covid-2023-08-30T1344Z.png"&gt;&lt;/p&gt;
&lt;address&gt;
Edited 2023-09-01 00:58 +01:00 to fix the link to the Debconf policy.&lt;/address&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=16518" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:16260</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/16260.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=16260"/>
    <title>I cycled to all the villages in alphabetical order</title>
    <published>2023-08-25T00:12:40Z</published>
    <updated>2023-08-25T00:33:16Z</updated>
    <category term="cycling"/>
    <category term="personal"/>
    <dw:security>public</dw:security>
    <dw:reply-count>11</dw:reply-count>
    <content type="html">&lt;p&gt;This last weekend I completed a bike rides project I started during the first Covid lockdown in 2020:&lt;/p&gt;
&lt;p&gt;I’ve cycled to every settlement (and radio observatory) within 20km of my house, in alphabetical order.&lt;/p&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h3&gt;Stir crazy&lt;/h3&gt;
&lt;p&gt;In early 2020, during the first lockdown, I was going a bit stir crazy. Clare said “you’re going very strange, you have to go out and get some exercise”. After a bit of discussion, we came up with this plan: I’d visit all the local villages, in alphabetical order.&lt;/p&gt;
&lt;h3&gt;Choosing the radius&lt;/h3&gt;
&lt;p&gt;I decided that I would pick a round number of kilometers, as the crow flies, from my house. 20km seemed about right. 25km would have included Ely, which would have been nice, but it would have added a great many places, all of them quite distant.&lt;/p&gt;
&lt;h3&gt;Software&lt;/h3&gt;
&lt;p&gt;I wrote a short Rust program to process OSM data into a list of places to visit, and their distances and bearings.&lt;/p&gt;
&lt;p&gt;You can download a tarball of &lt;a href="https://www.chiark.greenend.org.uk/~ijackson/2023/osm-alphabetical-destinations.tar.gz"&gt;the alphabetical villages scanner&lt;/a&gt;. (I haven’t published the git history because it has my house’s GPS coordinates in it, and because I committed the output files from which that location can be derived.)&lt;/p&gt;
&lt;h3&gt;The Rides&lt;/h3&gt;
&lt;p&gt;I set off on my first ride, to Aldreth, on Sunday the 31st of May 2020. The final ride collected Yelling, on Saturday the 19th of August 2023.&lt;/p&gt;
&lt;p&gt;I did quite a few rides in June and July 2020 - more than one a week. (I’d read the lockdown rules, and although some of the government messaging said you should stay near your house, that wasn’t in the legislation. Of course I didn’t go into any buildings or anything.)&lt;/p&gt;
&lt;p&gt;I’m not much of a morning person, so I often set off after lunch. For the longer rides I would usually pack a picnic. Almost all of the rides I did just by myself. There were a handful where I had friends along:&lt;/p&gt;
&lt;p&gt;Dry Drayton, which I collected with Clare, at night. I held my bike up so the light shone at the village sign, so we could take a photo of it.&lt;/p&gt;
&lt;p&gt;Madingley, Melbourn and Meldreth, which was quite an expedition with my friend Ben. We went out as far as Royston and nearby Barley (both outside my radius and not on my list) mostly just so that my project would have visited Hertfordshire.&lt;/p&gt;
&lt;p&gt;The Hemingfords, where I had my friend Matthew along, and we had a very nice pub lunch.&lt;/p&gt;
&lt;p&gt;Girton and Wilburton, where I visited friends. Indeed, I stopped off in Wilburton on one or two other occasions.&lt;/p&gt;
&lt;p&gt;And, of course, Yelling, for which there were four of us, again with a nice lunch (in Eltisley).&lt;/p&gt;
&lt;p&gt;I had relatively little mechanical trouble. My worst ride for this was Exning: I got three punctures that day. Luckily the last one was close to home.&lt;/p&gt;
&lt;p&gt;I often would stop to take lots of photos en-route. My mum in particular appreciated all the pretty pictures.&lt;/p&gt;
&lt;h3&gt;Rules&lt;/h3&gt;
&lt;p&gt;I decided on these rules:&lt;/p&gt;
&lt;p&gt;I would cycle to each destination, in order, and it would count as collected if I rode both there and back. I allowed collecting multiple villages in the same outing, provided I did them in the right order. (And obviously I was allowed to pass through places out of order, without counting them.)&lt;/p&gt;
&lt;p&gt;I tried to get a picture of the village sign, where there was one. Failing that, I got a picture of something in the village with the village’s name on it. I think the only one I didn’t manage this for was Westley Bottom; I had to make do with the word “Westley” on some railway level crossing equipment. In Barway I had to make do with a planning application, stuck to a pole.&lt;/p&gt;
&lt;p&gt;I tried not to enter and leave a village by the same road, if possible.&lt;/p&gt;
&lt;h3&gt;Edge cases&lt;/h3&gt;
&lt;p&gt;I had to make some decisions:&lt;/p&gt;
&lt;p&gt;I decided that I would consider the project complete if I visited everywhere whose &lt;em&gt;centre&lt;/em&gt; was within my radius. But the centre of a settlement is rather hard to define. I needed a hard criterion for my OpenStreetMap data mining: a place counted if there was any &lt;em&gt;node&lt;/em&gt;, &lt;em&gt;way&lt;/em&gt; or &lt;em&gt;relation&lt;/em&gt;, with the relevant &lt;code&gt;place&lt;/code&gt; tag, any part of which was within my ambit. That included some places that probably oughtn’t to have counted, but, fine.&lt;/p&gt;
&lt;p&gt;I also decided that I wouldn’t visit suburbs of Cambridge, separately from Cambridge itself. I don’t consider them separate settlements, at least, not if they’re conurbated with Cambridge. So that excluded Trumpington, for example. But I decided that Girton and Fen Ditton were (just) separable. Although the place where I consider Girton and Cambridge to nearly touch, is administratively well inside Girton, I chose to look at land use (on the ground, and in OSM data), rather than administrative boundaries.&lt;/p&gt;
&lt;p&gt;But I &lt;em&gt;did&lt;/em&gt; visit both Histon and Impington, and all each of the Shelfords and Stapleford, as separate entries in my list. Mostly because otherwise I’d have to decide whether to skip (say) Impington, or Histon. Whereas skipping suburbs of Cambridge in favour of Cambridge itself was an easy decision, and it also got rid of a bunch of what would have been quite short, boring, urban expeditions.&lt;/p&gt;
&lt;p&gt;I sorted all the Greats and Littles under G and L, rather than (say) “Shelford, Great”, which seemed like it would be cheating because then I would be able to do “Shelford, Great” and “Shelford, Little” in one go.&lt;/p&gt;
&lt;p&gt;Northstowe turned from mostly a building site into something that was arguably a settlement, during my project. It wasn’t included in the output of my original data mining. Of course it’s conurbated with Oakington - but happily, Northstowe inserts right before Oakington in the alphabetical list, so I decided to add it, visiting both the old and new in the same day.&lt;/p&gt;
&lt;p&gt;There are a bunch of other minor edge cases. Some villages have an outlying hamlet. Mostly I included these. There are some individual farms, which I generally didn’t count.&lt;/p&gt;
&lt;h3&gt;Some stats&lt;/h3&gt;
&lt;p&gt;I visited 150 villages plus the Lords Bridge radio observatory. The project took 3 years and 3 months to complete.&lt;/p&gt;
&lt;p&gt;There were 96 rides, totalling about 4900km. So my mean distance was around 51km. The median distance per ride was a little higher, at around 52 km, and the median duration (including stoppages) was about 2h40. The total duration, if you add them all up, including stoppages, was about 275h, giving a mean speed including photo stops, lunches and all, of 18kph.&lt;/p&gt;
&lt;p&gt;The longest ride was 89.8km, collecting Scotland Farm, Shepreth, and Six Mile Bottom, so riding across the Cam valley. The shortest ride was 7.9km, collecting Cambridge (obviously); and I think that’s the only one I did on my Brompton. The rest were all on my trusty Thorn Audax.&lt;/p&gt;
&lt;p&gt;My fastest ride (ranking by distance divided by time spent in motion) was to collect Haddenham, where I covered 46.3km in 1h39, giving an average speed in motion of 28.0kph.&lt;/p&gt;
&lt;p&gt;The most I collected in one day was 5 places: West Wickham, West Wratting, Westley Bottom, Westley Waterless, and Weston Colville. That was the day of the Wests. (There’s only one East: East Hatley.)&lt;/p&gt;
&lt;h3&gt;Map&lt;/h3&gt;
&lt;p&gt;Here is a pretty picture of all of my tracklogs:&lt;/p&gt;
&lt;p&gt;&lt;img width="1825" height="1866" style="width: 100%; height: 100%" src="https://www.chiark.greenend.org.uk/~ijackson/2023/alphabetical-villages-tracklogs.png"&gt;&lt;/p&gt;
&lt;address&gt;
Edited 2023-08-25 01:32 BST to correct a slip.&lt;/address&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=16260" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:16025</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/16025.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=16025"/>
    <title>DKIM: rotate and publish your keys</title>
    <published>2023-08-15T00:15:43Z</published>
    <updated>2023-09-30T23:20:34Z</updated>
    <category term="chiark"/>
    <category term="computers"/>
    <category term="dkim-rotate"/>
    <dw:security>public</dw:security>
    <dw:reply-count>6</dw:reply-count>
    <content type="html">&lt;p&gt;If you are an email system administrator, you are probably using DKIM to sign your outgoing emails. You should be rotating the key regularly and automatically, and publishing old private keys. I have just released &lt;a href="https://www.chiark.greenend.org.uk/pipermail/sgo-software-announce/2023/000086.html"&gt;dkim-rotate 1.0&lt;/a&gt;; dkim-rotate is a tool to do this key rotation and publication.&lt;/p&gt;
&lt;p&gt;If you are an email user, your email provider ought to be doing this. If this is not done, your emails are “non-repudiable”, meaning that if they are leaked, anyone (eg, journalists, haters) can verify that they are authentic, and prove that to others. This is not desirable (for you).&lt;/p&gt;
&lt;p&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Non-repudiation of emails is undesirable&lt;/h3&gt;
&lt;p&gt;This problem was described at some length in Matthew Green’s article &lt;a href="https://blog.cryptographyengineering.com/2020/11/16/ok-google-please-publish-your-dkim-secret-keys/"&gt;Ok Google: please publish your DKIM secret keys&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Avoiding non-repudiation sounds a bit like lying. After all, I’m advising creating a situation where some people can’t verify that something is true, even though it is. So I’m advocating casting doubt. Crucially, though, it’s doubt about facts that ought to be private. When you send an email, that’s between you and the recipient. Normally you don’t intend for anyone, anywhere, who happens to get a copy, to be able to verify that it was really you that sent it.&lt;/p&gt;
&lt;p&gt;In practical terms, this verifiability has already been used by journalists to verify stolen emails. Associated Press provide &lt;a href="https://github.com/associatedpress/verify-dkim"&gt;a verification tool&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Advice for all email users&lt;/h3&gt;
&lt;p&gt;As a user, you probably don’t want your emails to be non-repudiable. (Other people might want to be able to prove you sent some email, but your email system ought to serve your interests, not theirs.)&lt;/p&gt;
&lt;p&gt;So, your email provider ought to be rotating their DKIM keys, and publishing their old ones. At a rough guess, your provider probably isn’t :-(.&lt;/p&gt;
&lt;h4&gt;How to tell by looking at email headers&lt;/h4&gt;
&lt;p&gt;A quick and dirty way to guess is to have a friend look at the email headers of a message you sent. (It is important that the friend uses a different email provider, since often DKIM signatures are not applied within a single email system.)&lt;/p&gt;
&lt;p&gt;If your friend sees a &lt;code&gt;DKIM-Signature&lt;/code&gt; header then the message is DKIM signed. If they don’t, then it wasn’t. Most email traversing the public internet is DKIM signed nowadays; so if they don’t see the header probably they’re not looking using the right tools, or they’re actually on the same email system as you.&lt;/p&gt;
&lt;p&gt;In messages signed by a system running dkim-rotate, there will &lt;em&gt;also&lt;/em&gt; be a header about the key rotation, to notify potential verifiers of the situation. Other systems that avoid non-repudiation-through-DKIM might do something similar. dkim-rotate’s header looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DKIM-Signature-Warning: NOTE REGARDING DKIM KEY COMPROMISE
 https://www.chiark.greenend.org.uk/dkim-rotate/README.txt
 https://www.chiark.greenend.org.uk/dkim-rotate/ae/aeb689c2066c5b3fee673355309fe1c7.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But an email system might do half of the job of dkim-rotate: regularly rotating the key would cause the signatures of old emails to fail to verify, which is a good start. In that case there probably won’t be such a header.&lt;/p&gt;
&lt;h4&gt;Testing verification of new and old messages&lt;/h4&gt;
&lt;p&gt;You can also try verifying the signatures. This isn’t entirely straightforward, especially if you don’t have access to low-level mail tooling. Your friend will need to be able to save emails as &lt;em&gt;raw whole headers and body&lt;/em&gt;, un-decoded, un-rendered.&lt;/p&gt;
&lt;p&gt;If your friend is using a traditional Unix mail program, they should save the message as an mbox file. Otherwise, ProPublica have &lt;a href="https://www.propublica.org/nerds/authenticating-email-using-dkim-and-arc-or-how-we-analyzed-the-kasowitz-emails"&gt;instructions for attaching and transferring and obtaining the raw email&lt;/a&gt;. (Scroll down to “How to Check DKIM and ARC”.)&lt;/p&gt;
&lt;h5&gt;Checking that recent emails &lt;em&gt;are&lt;/em&gt; verifiable&lt;/h5&gt;
&lt;p&gt;Firstly, have your friend test that they can in fact verify a DKIM signature. This will demonstrate that the next test, where the verification is supposed to fail, is working properly and fails for the right reasons.&lt;/p&gt;
&lt;p&gt;Send your friend a test email now, and have them do this on a Linux system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    # save the message as test-email.mbox
    apt install libmail-dkim-perl # or equivalent on another distro
    dkimproxy-verify &amp;lt;test-email.mbox&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see output containing something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    originator address: ijackson@chiark.greenend.org.uk
    signature identity: @chiark.greenend.org.uk
    verify result: pass
    ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the output ontains &lt;code&gt;verify result: fail (body has been altered)&lt;/code&gt; then probably your friend didn’t manage to faithfully save the unalterered raw message.&lt;/p&gt;
&lt;h5&gt;Checking &lt;em&gt;old&lt;/em&gt; emails &lt;em&gt;cannot&lt;/em&gt; be verified&lt;/h5&gt;
&lt;p&gt;When you both have that working, have your friend find an older email of yours, from (say) month ago. Perform the same steps.&lt;/p&gt;
&lt;p&gt;Hopefully they will see something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    originator address: ijackson@chiark.greenend.org.uk
    signature identity: @chiark.greenend.org.uk
    verify result: fail (bad RSA signature)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or maybe&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    verify result: invalid (public key: not available)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This indicates that this old email can no longer be verified. That’s good: it means that anyone who steals a copy, can’t verify it either. If it’s leaked, the journalist who receives it won’t know it’s genuine and unmodified; they should then be suspicious.&lt;/p&gt;
&lt;p&gt;If your friend sees &lt;code&gt;verify result: pass&lt;/code&gt;, then they have verified that that old email of yours is genuine. Anyone who had a copy of the mail can do that. This is good for email thieves, but not for you.&lt;/p&gt;
&lt;h3&gt;For email admins: announcing dkim-rotate 1.0&lt;/h3&gt;
&lt;p&gt;I have been running dkim-rotate 0.4 on my infrastructure, since last August. and I had entirely forgotten about it: it has run flawlessly for a year. I was reminded of the topic by seeing DKIM in other blog posts. Obviously, it is time to decreee that &lt;a href="https://www.chiark.greenend.org.uk/pipermail/sgo-software-announce/2023/000086.html"&gt;dkim-rotate is 1.0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you’re a mail system administrator, your users are best served if you use something like dkim-rotate. The package is available in Debian stable, and supports Exim out of the box, but other MTAs should be easy to support too, via some simple ad-hoc scripting.&lt;/p&gt;
&lt;h3&gt;Limitation of this approach&lt;/h3&gt;
&lt;p&gt;Even with this key rotation approach, emails remain nonrepudiable for a short period after they’re sent - typically, a few days.&lt;/p&gt;
&lt;p&gt;Someone who obtains a leaked email very promptly, and shows it to the journalist (for example) right away, can still convince the journalist. This is not great, but at least it doesn’t apply to the vast bulk of your email archive.&lt;/p&gt;
&lt;p&gt;There are possible email protocol improvements which might help, but they’re quite out of scope for this article.&lt;/p&gt;
&lt;address&gt;Edited 2023-10-01 00:20 +01:00 to fix some grammar&lt;/address&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=16025" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:15789</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/15789.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=15789"/>
    <title>Private posts</title>
    <published>2023-08-11T18:56:40Z</published>
    <updated>2023-08-11T18:57:19Z</updated>
    <category term="administrivia"/>
    <category term="personal"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;p&gt;I have started to make private posts, accessible only to my Dreamwidth access list.&lt;/p&gt;
&lt;p&gt;If you’re a friend of mine and would like to be on that list, please contact me with your Dreamwidth username (or your &lt;a href="https://en.wikipedia.org/wiki/Openid"&gt;OpenID&lt;/a&gt;).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=15789" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:15336</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/15336.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=15336"/>
    <title>Installing Debian bookworm without systemd</title>
    <published>2023-07-19T13:25:46Z</published>
    <updated>2023-07-19T13:26:01Z</updated>
    <category term="debian"/>
    <category term="computers"/>
    <dw:security>public</dw:security>
    <dw:reply-count>10</dw:reply-count>
    <content type="html">&lt;h2&gt;Instructions&lt;/h2&gt;
&lt;ol type="1"&gt;
&lt;li&gt;&lt;p&gt;Get the official installation image from &lt;a href="https://www.debian.org/releases/bookworm/amd64/ch04s01.en.html"&gt;the usual locations&lt;/a&gt;. I got the netinst CD image via BitTorrent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boot from the image and go through the installation in the normal way.&lt;/p&gt;
&lt;ol type="a"&gt;
&lt;li&gt;&lt;p&gt;You may want to select an alternative desktop environment (and unselect GNOME). These steps have been tested with MATE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop when you are asked to remove the installation media and reboot.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Press Alt + Right arrow to switch to the text VC. Hit return to activate the console and run the following commands (answering yes as appropriate):&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;chroot /target bash
apt-get install sysvinit-core elogind ntp dbus-x11
apt-get autoremove
exit&lt;/code&gt;&lt;/pre&gt;
&lt;ol start="4" type="1"&gt;
&lt;li&gt;&lt;p&gt;Observe the output from the &lt;code&gt;apt-get install&lt;/code&gt;. If your disk arrangements are unusual, that may generate some error messages from &lt;code&gt;update-initramfs&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go back to the installer VC with Alt + Left arrow. If there were no error messages above, you may tell it to reboot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If there were error messages (for example, I found that if there was disk encryption, alarming messages were printed), tell the installer to go “Back”. Then ask it to “Install GRUB bootloader” (again). After that has completed, you may reboot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enjoy your Debian system without systemd.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Discussion&lt;/h2&gt;
&lt;p&gt;This is pleasingly straightforward, albeit with an ugly wart. This recipe was not formally developed and tested; it’s just what happened when I tried to actually perform this task.&lt;/p&gt;
&lt;p&gt;The official installation guide has &lt;a href="https://wiki.debian.org/Init#Changing_the_init_system_-_at_installation_time"&gt;similar instructions&lt;/a&gt; although they don’t seem to have the initramfs workaround.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;update-initramfs&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The need to go back and have the installer reinstall grub is because if your storage is not very straightforward, the &lt;code&gt;update-initramfs&lt;/code&gt; caused by &lt;code&gt;apt-get install&lt;/code&gt; apparently doesn’t have all the right context. I haven’t investigated this at all; indeed, I don’t even really know that the initramfs generated in step 3 above was broken, although the messages did suggest to me that important pieces or config might have been omitted. Instead, I simply chose to bet that it might be broken, but that the installer would know what to do. So I used the installer’s “install GRUB bootloader” option, which does regenerate the initramfs. So, I don’t know that step 6 is necessary.&lt;/p&gt;
&lt;p&gt;In principle it would be better to do the switch from systemd to sysvinit earlier in the installation process, and under the control of the installer. But by default the installer goes straight from the early setup questions through to the “set the time” or “reboot” questions, without stopping. One could use the expert mode, or modify the command line, or something, but all of those things are, in practice, a lot more typing and/or interaction. And as far as I’m aware the installer doesn’t have an option for avoiding systemd .&lt;/p&gt;
&lt;h3&gt;The &lt;code&gt;apt-get install&lt;/code&gt; line&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;sysvinit-core&lt;/code&gt; is the principal part of the sysvinit init system. Asking to install that causes the deinstallation of systemd’s init and ancillary packages.&lt;/p&gt;
&lt;p&gt;systemd refuses to allow itself to be deinstalled, if it is already running, so if you boot into the systemd system you can’t then switch init system. This is why the switch is best done at install time. If you’re too late, there are &lt;a href="https://wiki.debian.org/Init#Changing_the_init_system_-_on_a_running_system"&gt;instructions for changing init system post-installation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;elogind&lt;/code&gt; is a forked version of some of systemd’s user desktop session functionality. In practice modern desktop environments need this; without it, apt will want to remove things you probably want to keep. Even if you force it, you may find that your desktop environment can’t adjust the audio volume, etc.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ntp&lt;/code&gt; is needed because nowadays the default network time client is systemd-timesyncd (which is a bad idea even on systems &lt;em&gt;with&lt;/em&gt; systemd as init). We need to specify it because the package dependencies don’t automatically give you any replacement for systemd-timesyncd.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dbus-x11&lt;/code&gt; is a glue component. In theory it ought to be installed automatically. However, there have been problems with the dependencies that meant that (for example) asking for emacs would try to switch the init system. Specifying &lt;code&gt;dbus-x11&lt;/code&gt; explicitly is a workaround for that, which I nowadays adopt out of caution. Perhaps it is no longer needed.&lt;/p&gt;
&lt;p&gt;(On existing systems, it may be necessary to manually install &lt;code&gt;orphan-sysvinit-scripts&lt;/code&gt;, which exists as a suboptimal technical workaround for the sociopolitical problems of hostile package maintainers and Debian’s governance failures. The recipe above seems to install this package automatically.)&lt;/p&gt;
&lt;h3&gt;usrmerge&lt;/h3&gt;
&lt;p&gt;This recipe results in a system which has merged-/usr via symlinks. This configuration is a bad one. Ideally usrmerge-via-symlinks would be avoided.&lt;/p&gt;
&lt;p&gt;The un-merged system is declared “not officially supported by Debian” and key packages try very hard to force it on users. However, merged-/usr-via-symlinks is full of bugs (mostly affecting package management) which are far too hard to fix (a project by some folks to try to do so has given up).&lt;/p&gt;
&lt;p&gt;I suspect un-merged systems will suffer from fewer bugs in practice. But I don’t know how to persuade d-i to make one.&lt;/p&gt;
&lt;h3&gt;Installer images&lt;/h3&gt;
&lt;p&gt;I think there is room in the market for an unofficial installer image which installs without systemd and perhaps without usrmerge. I don’t have the effort for making such a thing myself.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Installing Debian without systemd is fairly straightforward.&lt;/p&gt;
&lt;p&gt;Operating Debian without systemd is a pleasure and every time one of my friends has some systemd-induced lossage I get to feel smug.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=15336" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:14929</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/14929.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=14929"/>
    <title>The Rust Foundation's bad draft trademark policy</title>
    <published>2023-04-19T16:36:19Z</published>
    <updated>2023-04-19T16:36:19Z</updated>
    <category term="legal"/>
    <category term="rust"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;h2&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;The Rust Foundation’s proposed new trademark policy is far too restrictive, and will cause (more) drama unless it is substantially revised.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#process"&gt;Process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#substance"&gt;Substance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#values"&gt;Values&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#next-steps"&gt;Next steps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#echoes-of-a-dispute-from-2006"&gt;Echoes of a dispute from 2006&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Process&lt;/h2&gt;
&lt;p&gt;“Rust” is a trademark owned by the Foundation.&lt;/p&gt;
&lt;p&gt;The Rust Foundation still seems to be finding its feet. Evidently, one of the items on its backlog was to update the trademark policy. Apparently they have been working on this for some time, in an informal working group.&lt;/p&gt;
&lt;p&gt;In August, there was a survey. (I saw it in This Week In Rust, the community-curated newsletter where most important stuff appears, and responded.) I don’t think the results of this survey have been published anywhere.&lt;/p&gt;
&lt;p&gt;Last week (12th April) the Foundation published &lt;a href="https://blog.rust-lang.org/inside-rust/2023/04/12/trademark-policy-draft-feedback.html"&gt;an official Inside Rust blog post&lt;/a&gt; linking to a draft. They included a link to a feedback survey, closing on the 17th of April i.e., it was open for 5 days.&lt;/p&gt;
&lt;p&gt;This is far too short a period for formal feedback on such a draft. Especially given that this process has apparently already been generating significant controversy within parts of the Rust community.&lt;/p&gt;
&lt;h2&gt;Substance&lt;/h2&gt;
&lt;p&gt;Overall, this policy is poor. It is far too restrictive.&lt;/p&gt;
&lt;p&gt;It is likely to lead to (further) controversy and argument, including conflicts with Rust’s downstreams. It does not serve the needs of the Rust community.&lt;/p&gt;
&lt;p&gt;In particular, the Rust community does not need the trademark to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;“Maintain the quality” of software called Rust.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prevent people distributing badly-modified versions of its software, even called “Rust”, provided that users know what they are getting.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The community &lt;em&gt;does&lt;/em&gt; need the trademark to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prevent people impersonating the Rust Project (for example by registering competing domain names).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prevent people economically exploiting the value of the brand by holding shabby or vacuous conferences etc. (so requiring approval for e.g. conferences makes sense).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It &lt;em&gt;might&lt;/em&gt; be useful to use the trademark to strengthen licensing or CoC compliance. For example, good faith redistributions of a modified Rust, as “Rust”, would be Free Software, even though the copyright licence permits proprietary derivatives; so use of the Rust trademark should probably require use of a Free licence.&lt;/p&gt;
&lt;p&gt;There should be a series of blanket permissions to use the word “Rust” in for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Free Software distributions derived from official Rust software, provided it’s recognisably similar. (I.e., you must change its name if you make other big changes too.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Free Software libraries written in Rust, or interfacing to Rust, in non-Rust-specific software repositories (including source hosting systems like gitlab, distro package managers e.g. Debian apt, and package managers for other languages e.g. npm).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Currently there aren’t. For example the current Debian practice of calling Rust libraries &lt;code&gt;rust-&amp;lt;name-of-crate&amp;gt;&lt;/code&gt; is probably in violation.&lt;/p&gt;
&lt;p&gt;There are a number of more detailed problems with the wording.&lt;/p&gt;
&lt;h2&gt;Values&lt;/h2&gt;
&lt;p&gt;The policy has all the hallmarks of excessive influence from traditional trademark lawyers and not enough influence from the Free Software community.&lt;/p&gt;
&lt;p&gt;I would like to remind the Free Software activists on the inside of this process that the lawyers are there to serve you and the community.&lt;/p&gt;
&lt;p&gt;The values embodied in trademark law often conflict with the values of the Free Software community. The Rust Project should adopt a trademark policy which follows the community’s values - even if that might weaken our ability to sue evildoers.&lt;/p&gt;
&lt;h2&gt;Next steps&lt;/h2&gt;
&lt;p&gt;The Foundation should take a step back and pause the process.&lt;/p&gt;
&lt;p&gt;Then, the Foundation should restart the process from a much earlier stage, with much wider publicity. Each stage should be widely advertised to the whole community, with opportunities for feedback.&lt;/p&gt;
&lt;p&gt;This should include publishing the results of the August 2022 survey. The Foundation should publish a sketch of the legal advice they have received, publicly say what the plausible options are and what their consequences might be (for the community, for downstreams, and for the Foundation’s enforcement ability).&lt;/p&gt;
&lt;p&gt;(Some of this will no doubt repeat the work that has been done in the informal trademark working group. That work wasn’t widely enough advertised.)&lt;/p&gt;
&lt;h2&gt;Echoes of a dispute from 2006&lt;/h2&gt;
&lt;p&gt;Mozilla made a very similar mistake with Firefox in 2006.&lt;/p&gt;
&lt;p&gt;The official policy stated that no-one was allowed to distribute Firefox with any patches, unless those patches had been pre-approved by Mozilla.&lt;/p&gt;
&lt;p&gt;Debian is committed to Software Freedom. This must includes the freedom to modify the software as one sees fit, even if the original authors don’t agree.&lt;/p&gt;
&lt;p&gt;Now, overly-restrictive trademark policies are hardly new. Debian often takes the practical view that usually the upstream with such a policy doesn’t really mean it.&lt;/p&gt;
&lt;p&gt;But Mozilla decided they &lt;em&gt;did&lt;/em&gt; mean it. They contacted Debian asking for Debian to get their patches approved.&lt;/p&gt;
&lt;p&gt;Since that wasn’t acceptable to Debian, they stopped using the word “Firefox”. For a decade, Debian’s Firefox browser was called &lt;a href="https://en.wikipedia.org/wiki/Iceweasel"&gt;“Iceweasel”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We don’t want something similar happening to “Rust”.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=14929" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:14666</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/14666.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=14666"/>
    <title>Never use git submodules</title>
    <published>2023-03-02T19:48:20Z</published>
    <updated>2023-03-02T19:48:20Z</updated>
    <category term="computers"/>
    <category term="git"/>
    <dw:security>public</dw:security>
    <dw:reply-count>3</dw:reply-count>
    <content type="html">&lt;h2&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;git submodules are &lt;em&gt;always the wrong solution&lt;/em&gt;. Yes, even the to the problem they were specifically invented to solve.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#what-is-wrong-with-git-submodules"&gt;What is wrong with git submodules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#better-alternatives-to-git-submodules"&gt;Better alternatives to git submodules&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#use-git-subtree"&gt;Use git subtree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#just-have-a-monorepo"&gt;Just have a monorepo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#use-a-package-management-system-and-explicit-dependencies"&gt;Use a package management system, and explicit dependencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#use-the-multiple-repository-tool-mr"&gt;Use the multiple repository tool &lt;code&gt;mr&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#have-your-build-expect-to-find-the-dependency-in-..-its-parent-dir"&gt;Have your build expect to find the dependency in &lt;code&gt;..&lt;/code&gt;, its parent dir&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#provide-an-ad-hoc-in-tree-script-to-download-the-dependency"&gt;Provide an ad-hoc in-tree script to download the dependency&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h2&gt;What is wrong with git submodules&lt;/h2&gt;
&lt;p&gt;There are two principal sets of reasons why they are terrible:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fundamentally wrong design. They break the git data model in multiple ways. Critical ways include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A git object in your repository is no longer necessarily resolvable/interpetable to meaningful data. (Shallow clones have the same issue but only with respect to history. git submodules do this for the contents of the tree.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;git submodules violate the usual rule that all URLs, hostnames, and so on, used by git, are provided by the git configuration and the user, rather than appearing in-tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;git submodules introduce completely new states your tree can be in, many of them strange or undesirable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wrong behaviour in detail. git’s behaviour with submodules is often buggy or bizarre. Some of these problems are implied by the design, but many of them are additional unforced errors. Some of the defects occur even if you don’t &lt;code&gt;git submodule init&lt;/code&gt;, so affect &lt;em&gt;all&lt;/em&gt; programs and users which interact with your tree.&lt;/p&gt;
&lt;p&gt;Just a few examples of lossage with submodules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;git checkout no longer reliably switches branches&lt;/li&gt;
&lt;li&gt;editing files and trying to commit them no longer reliably works&lt;/li&gt;
&lt;li&gt;locally pulling a new version from main no longer reliably works&lt;/li&gt;
&lt;li&gt;git ls-files can disagree with git log and git cat-file&lt;/li&gt;
&lt;li&gt;URLs from .gitmodules: they can be malicious; they can end up cached in individual trees’ (individual users’) .git/config; etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Generally, normal git operations like git checkout and git pull can leave the submodule in a weird state where you have to run one of the git submodule commands to fix it up. Often the easiest way (especially for a non-expert) to get back to a normal state is to throw the whole tree away and re-clone it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ultimately, this means that the author of a program which works with git has two options:&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;&lt;p&gt;Don’t support submodules. Tell users of your program who file bugs involving submodules that they’re not supported.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do an enormous amount of extra work: At every point you interact with git, experiment to see what bizarre behaviour submodules exhibit, and write code to deal with all the possibilities.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a result, a substantial subset of git tooling is broken in the presence of submodules. This is especially true of local automation and tooling, which is otherwise an effective way of improving your processes. But, of course this also applies to git itself! Which is one of the causes of the bugs that git itself has when working with submodules.&lt;/p&gt;
&lt;h2&gt;Better alternatives to git submodules&lt;/h2&gt;
&lt;p&gt;In my opinion git submodule is &lt;em&gt;never&lt;/em&gt; the right answer. Often, git submodule is the &lt;em&gt;worst&lt;/em&gt; answer and &lt;em&gt;any&lt;/em&gt; of the following would be better.&lt;/p&gt;
&lt;h3&gt;Use git subtree&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://manpages.debian.org/stable/git-man/git-subtree.1.en.html"&gt;git subtree&lt;/a&gt; solves many of the same problems as git submodule, but it does not violate the git data model.&lt;/p&gt;
&lt;p&gt;Use this when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You want to track and use, in-tree, a separate project which ought to have its own identity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The separate project is of reasonable size (compared to your own).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With git subtree, people and programs that do not need to specifically interact with the upstream for the subtree, do not need to know that it even &lt;em&gt;is&lt;/em&gt; a subtree. They can make and switch branches, commit, and so on, as they like.&lt;/p&gt;
&lt;p&gt;git subtree can automatically separate out changes made in the downstream, for application to (or submission to) the upstream branch.&lt;/p&gt;
&lt;p&gt;I have used git subtree and found it capable and convenient, and pleasingly straightforward.&lt;/p&gt;
&lt;h3&gt;Just have a monorepo&lt;/h3&gt;
&lt;p&gt;If you are the upstream for all the pieces, it is often more convenient to merge the git trees into a single git tree with a single history.&lt;/p&gt;
&lt;p&gt;Use this when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The maintenance of all the pieces is &lt;em&gt;organisationally&lt;/em&gt; and &lt;em&gt;politically&lt;/em&gt; cohesive enough that you can share a git history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The whole monorepo would be of reasonable size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any long-running branches you need to make are for release channels, or the similar, not for having separate versions of the internal dependencies for the different pieces in the monorepo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Use a package management system, and explicit dependencies&lt;/h3&gt;
&lt;p&gt;Instead of subsuming the dependency’s tree into your own, give the dependency a proper API and reuse it via a package management system. (If necessary, maintain a proper downstream fork of the dependency.)&lt;/p&gt;
&lt;p&gt;The package manager might be be:&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;a distro-style package management system such as &lt;code&gt;apt&lt;/code&gt;+&lt;code&gt;dpkg&lt;/code&gt;+&lt;a href="https://manpages.debian.org/stable/sbuild/sbuild.1.en.html"&gt;&lt;code&gt;sbuild&lt;/code&gt;&lt;/a&gt; (or a proprietary/private dependency-managing build system); or&lt;/li&gt;
&lt;li&gt;a language specific package manager (eg &lt;code&gt;cargo&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Use this when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You are already using, or familiar with, a suitable package manager,&lt;/li&gt;
&lt;li&gt;The API provided by the dependency can be reasonably represented in that package manager (even if unstably).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Use the multiple repository tool &lt;code&gt;mr&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://manpages.debian.org/stable/myrepos/mr.1.en.html"&gt;&lt;code&gt;mr(1)&lt;/code&gt;&lt;/a&gt; is a tool which lets you conveniently manage a possibly large number of trees, usually as sibling directories.&lt;/p&gt;
&lt;p&gt;I haven’t used this myself but it looks capable and straightforward. As I understand it, you’d usually use this in combination with the &lt;code&gt;..&lt;/code&gt;-based dependency expectation I describe below.&lt;/p&gt;
&lt;p&gt;It seems like it would be good when your project has a fair number of “foreign” dependencies.&lt;/p&gt;
&lt;h3&gt;Have your build expect to find the dependency in &lt;code&gt;..&lt;/code&gt;, its parent dir&lt;/h3&gt;
&lt;p&gt;This is a very lightweight solution. Just have the files in your tree refer to the dependencies with &lt;code&gt;../dependency-name/&lt;/code&gt;. Expect users (and programs) to manually clone and update the right dependency version, alongside your project.&lt;/p&gt;
&lt;p&gt;Consider this when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Your project is at an early stage and you want to get going quickly and worry about this build system stuff later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The dependency is disabled by default, and almost never neeeded.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every program or human that wants to run a build that needs the dependency will need to know to clone the dependency, and keep it up to date. This will be a nuisance, and if you’re doing CI it will mean some custom CI scripting. But this is all probably still better than git submodules. At least it will be completely obvious to everyone what’s going on, how to make changes to the dependency, and so on.&lt;/p&gt;
&lt;h3&gt;Provide an ad-hoc in-tree script to download the dependency&lt;/h3&gt;
&lt;p&gt;As a last resort, you can embed the URL to find your dependency, and the instructions for downloading it, in your top-level package’s build system. This is clumsy and awkward, but, astonishingly, it is less painful than git submodules.&lt;/p&gt;
&lt;p&gt;Use this when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Most people using/building your software won’t need the dependency at all.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In particular, most people won’t need to edit the dependency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;None of the other options are suitable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usually the downstream build runes should git clone the dependency, and the downstream tree should name the precise commitid needed.&lt;/p&gt;
&lt;p&gt;Try to avoid this situation. It’s not a good place to be. But:&lt;/p&gt;
&lt;h4&gt;Yes, really, git submodule is worse than ad-hoc Makefile runes&lt;/h4&gt;
&lt;p&gt;The ad-hoc shell script route feels very hacky. But it has some important advantages over git submodule. In particular, unlike with git submodule, this approach (like most of the others I suggest) means that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All tooling that expects to clone your repository, make changes, do builds, track changes, etc., will work correctly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are in precise control of when/whether the download occurs: ie, you can arrange to download the dependency precisely when it’s needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are in precise control of your version management and checking of the dependency: your script controls what version of the dependency to use, and whether that should be “pinned” or dynamically updated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’m not advocating ad-hoc runes over git submodules because I like ad-hoc runes or think they’re a good idea. It’s just that git submodule is really so very very bad.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=14666" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:14345</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/14345.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=14345"/>
    <title>derive-adhoc: powerful pattern-based derive macros for Rust</title>
    <published>2023-02-03T00:29:28Z</published>
    <updated>2023-02-03T00:34:28Z</updated>
    <category term="computers"/>
    <category term="rust"/>
    <category term="derive-adhoc"/>
    <dw:security>public</dw:security>
    <dw:reply-count>2</dw:reply-count>
    <content type="html">&lt;h2&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;Have you ever wished that you could that could write a new &lt;code&gt;derive&lt;/code&gt; macro without having to mess with procedural macros?&lt;/p&gt;
&lt;p&gt;Now you can!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.rs/derive-adhoc/latest/derive_adhoc"&gt;&lt;code&gt;derive-adhoc&lt;/code&gt;&lt;/a&gt; lets you write a &lt;code&gt;#[derive]&lt;/code&gt; macro, using a template syntax which looks a lot like &lt;code&gt;macro_rules!&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It’s still 0.x - so unstable, and maybe with sharp edges. We want feedback!&lt;/p&gt;
&lt;p&gt;And, the documentation is still very terse. It is doesn’t &lt;em&gt;omit&lt;/em&gt; anything, but, it is severely lacking in examples, motivation, and so on. It will suit readers who enjoy dense reference material.&lt;/p&gt;
&lt;a name="cutid1"&gt;&lt;/a&gt;
&lt;h2&gt;Background - Rust’s two (main) macro systems&lt;/h2&gt;
&lt;p&gt;Rust has two principal macro systems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://doc.rust-lang.org/book/ch19-06-macros.html#declarative-macros-with-macro_rules-for-general-metaprogramming"&gt;&lt;code&gt;macro_rules!&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; (also known as “macros by example”) is relatively straightforward to use. You have some control over the argument syntax for your macro, and then you can generate output code using a pattern-style template.&lt;/p&gt;
&lt;p&gt;But, its power is limited. In particular, although you can specify a pattern to match the arguments to your macro, the pattern matching system has serious limitations (for example, it has a very hard time with Rust’s generic type parameters). Also, you can’t feed existing pieces of your program to a macro without passing them as arguments: so you must write them out twice, or have the macro re-generate its own arguments as a side-effect.&lt;/p&gt;
&lt;p&gt;Because of these limitations, code which makes heavy use of &lt;code&gt;macro_rules!&lt;/code&gt; macros can be less than clear.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://doc.rust-lang.org/book/ch19-06-macros.html#procedural-macros-for-generating-code-from-attributes"&gt;Procedural macros&lt;/a&gt;&lt;/strong&gt; are an extremely powerful and almost fully general code-rewriting macro facility. They work by taking actual rust code (represented as a stream of tokens) as their input, running arbitrary computations, and then generating a new stream of tokens as an output. Procedural macros can be applied (with &lt;code&gt;derive&lt;/code&gt;) to Rust’s data structure definitions, to parse them, and autogenerate data-structure-dependent code. They are the basis of many extremely powerful facilities, both in standard Rust, and in popular Rust libraries.&lt;/p&gt;
&lt;p&gt;However, procedural macros are hard to write. You must deal with libraries for parsing Rust source code out of tokens. You must generate compile errors manually. You often end up matching on Rust syntax in excruciating detail. Procedural macros run in an inconvient execution context and must live in a separate Rust package. And so on.&lt;/p&gt;
&lt;h2&gt;“Derive by example” with &lt;code&gt;derive-adhoc&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;derive-adhoc&lt;/code&gt; aims to provide much of the power of proc macros, with the convenience of &lt;code&gt;macro_rules!&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You write a template which is expanded for a data structure (for a &lt;code&gt;struct&lt;/code&gt;, say). &lt;code&gt;derive-adhoc&lt;/code&gt; takes care of parsing the struct, and gives you convenient expansion variables for use in your template.&lt;/p&gt;
&lt;h3&gt;A simple example - deriving &lt;code&gt;Clone&lt;/code&gt; without inferred trait bounds&lt;/h3&gt;
&lt;p&gt;Here is a simple example, taken from &lt;a href="https://gitlab.torproject.org/Diziet/rust-derive-adhoc/-/blob/8b307207263b97d8e12cddeeebf3cc27502ac331/tests/expand/clone.rs"&gt;&lt;code&gt;clone.rs&lt;/code&gt;&lt;/a&gt;, in &lt;code&gt;derive-adhoc&lt;/code&gt;’s &lt;a href="https://gitlab.torproject.org/Diziet/rust-derive-adhoc/-/tree/8b307207263b97d8e12cddeeebf3cc27502ac331/tests/expand"&gt;test suite&lt;/a&gt;; &lt;a href="https://gitlab.torproject.org/Diziet/rust-derive-adhoc/-/blob/8b307207263b97d8e12cddeeebf3cc27502ac331/tests/expand/clone.expanded.rs"&gt;&lt;code&gt;clone.expanded.rs&lt;/code&gt;&lt;/a&gt; shows the result of the macro expansion.&lt;/p&gt;
&lt;p&gt;This showcases very few of &lt;code&gt;derive-adhoc&lt;/code&gt;’s features, but it gives a flavour.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  // Very simple `Clone`
  //
  // Useful because it doesn&amp;#39;t infer Clone bounds on generic type
  // parameters, like std&amp;#39;s derive of Clone does.  Instead, it
  // unconditionally attempts to implement Clone.
  //
  // Only works on `struct { }` structs.
  //
  // (This does a small subset of what the educe crate&amp;#39;s `Clone` does.)
  define_derive_adhoc!{
      MyClone =

      impl&amp;lt;$tgens&amp;gt; Clone for $ttype {
          fn clone(&amp;amp;self) -&amp;gt; Self {
              Self {
                  $(
                      $fname: self.$fname.clone(),
                  )
              }
          }
      }
  }

  // If we were to `#[derive(Clone)]`, DecoratedError&amp;lt;io::Error&amp;gt; wouldn&amp;#39;t
  // be Clone, because io::Error isn&amp;#39;t, even though the Arc means we can clone.
  #[derive(Adhoc)]
  #[derive_adhoc(MyClone)]
  struct DecoratedError&amp;lt;E&amp;gt; {
      context: String,
      error: Arc&amp;lt;E&amp;gt;,
  }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Replacing an existing bespoke proc macro - a more complex example&lt;/h3&gt;
&lt;p&gt;Recently, I thought I would try out derive-adhoc in &lt;a href="https://www.chiark.greenend.org.uk/~ianmdlvl/hippotat/current/docs/"&gt;Hippotat&lt;/a&gt;, a personal project of mine, which currently uses a project-specific proc macro. This was an enjoyable experience.&lt;/p&gt;
&lt;p&gt;I found the &lt;a href="https://salsa.debian.org/iwj/hippotat/-/blob/98b28d5d5dab0c68c5512448cc735f53828a6869/src/config.rs#L65"&gt;new code&lt;/a&gt; a huge improvement over &lt;a href="https://salsa.debian.org/iwj/hippotat/-/blob/a6ac94b4922602af64f22b86ba5347ad95fcda44/macros/macros.rs#L68"&gt;the old code&lt;/a&gt;. I intend to tidy up this branch and merge it into Hippotat’s mainline, at some suitable point in the release cycles of Hippotat and &lt;code&gt;derive-adhoc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I won’t copy the whole thing here, but: now we have things like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  pub struct InstanceConfig {
    #[adhoc(special=&amp;quot;link&amp;quot;, skl=&amp;quot;SKL::None&amp;quot;)]  pub link: LinkName,
  ...

  derive_adhoc!{
    InstanceConfig:

    fn resolve_instance(rctx: &amp;amp;ResolveContext) -&amp;gt; InstanceConfig {
      InstanceConfig {
        $(
          $fname: rctx.
            ${if fmeta(special) {
              ${paste special_ ${fmeta(special)}}
            } else {&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of this kind of awfulness:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   } else if attr.path == parse_quote!{ special } {
     let meta = match attr.parse_meta().unwrap() {
       Meta::List(list) =&amp;gt; list,
       _ =&amp;gt; panic!(),
     };
     let (tmethod, tskl) = meta.nested.iter().collect_tuple().unwrap();
     fn get_path(meta: &amp;amp;NestedMeta) -&amp;gt; TokenStream {
       match meta {
         NestedMeta::Meta(Meta::Path(ref path)) =&amp;gt; path.to_token_stream(),
         _ =&amp;gt; panic!(),
       }
     }
     method = get_path(tmethod);
     *skl.borrow_mut() = Some(get_path(tskl));
   }&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;History and acknowledgements&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;derive-adhoc&lt;/code&gt; was my project proposal in last year’s Tor Project Hackweek. Thanks to Tor for giving us the space to do something like this.&lt;/p&gt;
&lt;p&gt;Nick Mathewson joined in, and has made important code contributions, also given invaluable opinions and feedback. Thanks very much to Nick - I look forward to working on this more with you. I take responsibility for all bugs, mistakes, and misjudgements of taste.&lt;/p&gt;
&lt;h2&gt;Future plans&lt;/h2&gt;
&lt;p&gt;We’re hoping &lt;code&gt;derive-adhoc&lt;/code&gt; will become a widely-used library, significantly improving Rust’s expressive power at the same time as improving the clarity of macro-using programs.&lt;/p&gt;
&lt;p&gt;We would like to see the wider Rust community experiment with it and give us feedback. Who knows? Maybe it will someday inspire a “Derive By Example” feature in standard Rust.&lt;/p&gt;
&lt;p&gt;Two words of warning, though:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The documentation is currently very terse. Many readers will find it far too dense and dry for easy comprehension. The examples are sparse, not well integrated, and not very well explained. We will need your patience - and and your help - as we try to improve it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The library and its template syntax are still unstable. As more people try &lt;code&gt;derive_adhoc&lt;/code&gt;, we expect to find areas where the syntax and behavior need to improve. While still at &lt;code&gt;0.x&lt;/code&gt;, we’ll be keen to make those improvements, without much regard to backward compatibility. So, for now, expect breaking changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We hope to release a more-stable and better-documented version 1.x later this lear.&lt;/p&gt;
&lt;p&gt;So, please try it out and let us know what you think.&lt;/p&gt;
&lt;h2&gt;Documentation and references about &lt;code&gt;derive-adhoc&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.rs/derive-adhoc/latest/derive_adhoc/index.html#"&gt;Top-level documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lib.rs/crates/derive-adhoc"&gt;&lt;code&gt;derive-adhoc&lt;/code&gt; on lib.rs&lt;/a&gt; and &lt;a href="https://crates.io/crates/derive-adhoc"&gt;crates.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/derive-adhoc/latest/derive_adhoc/doc_template_syntax/index.html"&gt;Template syntax reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.torproject.org/Diziet/rust-derive-adhoc/-/tree/8b307207263b97d8e12cddeeebf3cc27502ac331/tests/expand"&gt;Examples / test cases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/derive-adhoc/latest/derive_adhoc/doc_implementation/index.html"&gt;How it works&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;address&gt;edited 2023-02-03 00:34 Z to fix a typo&lt;/address&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=14345" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:14161</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/14161.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=14161"/>
    <title>SGO (and my) VPN and network access tools - in bookworm</title>
    <published>2023-01-14T00:41:35Z</published>
    <updated>2023-01-14T00:41:35Z</updated>
    <category term="secnet"/>
    <category term="computers"/>
    <category term="chiark"/>
    <category term="userv"/>
    <category term="hippotat"/>
    <category term="debian"/>
    <dw:security>public</dw:security>
    <dw:reply-count>1</dw:reply-count>
    <content type="html">&lt;p&gt;Recently, we managed to get secnet and hippotat into Debian. They are on track to go into Debian bookworm. This completes in Debian the set of VPN/networking tools I (and other &lt;a href="https://www.greenend.org.uk/"&gt;Greenend&lt;/a&gt;) folks have been using for many years.&lt;/p&gt;
&lt;p&gt;The Sinister Greenend Organisation’s suite of network access tools consists mainly of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;secnet&lt;/code&gt; - VPN.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hippotat&lt;/code&gt; - IP-over-HTTP (workaround for bad networks)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;userv ipif&lt;/code&gt; - user-created network interfaces&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;secnet&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.chiark.greenend.org.uk/pipermail/sgo-software-announce/2023/000081.html"&gt;secnet&lt;/a&gt; is our very mature VPN system.&lt;/p&gt;
&lt;p&gt;Its basic protocol idea is similar to that in Wireguard, but it’s much older. Differences from Wireguard include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Comes with some (rather clumsy) provisioning tooling, supporting almost any desired virtual network topology. In the SGO we have a complete mesh of fixed sites (servers), and a number of roaming hosts (clients), each of which can have one or more sites as its home.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No special kernel drivers required. Everything is userspace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An exciting “polypath” mode where packets are sent via multiple underlying networks in parallel, offering increased reliability for roaming hosts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Portable to non-Linux platforms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A much older, and less well audited, codebase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Very flexible configuration arrangements, but things are also under-documented and to an extent under-productised.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hasn’t been ported to phones/tablets.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;secnet was originally written by Stephen Early, starting in 1996 or so. I inherited it some years ago and have been maintaining it since. It’s mostly written in C.&lt;/p&gt;
&lt;h2&gt;Hippotat&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.chiark.greenend.org.uk/pipermail/sgo-software-announce/2023/000082.html"&gt;Hippotat&lt;/a&gt; is best described by copying the intro from the docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hippotat is a system to allow you to use your normal VPN, ssh, and other applications, even in broken network environments that are only ever tested with “web stuff”.&lt;/p&gt;
&lt;p&gt;Packets are parcelled up into HTTP POST requests, resembling form submissions (or JavaScript XMLHttpRequest traffic), and the returned packets arrive via the HTTP response bodies.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It doesn’t rely on TLS tunnelling so can work even if the local network is trying to intercept TLS. I recently &lt;a href="https://diziet.dreamwidth.org/12934.html"&gt;rewrote Hippotat in Rust&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;&lt;code&gt;userv ipif&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;userv ipif&lt;/code&gt; is one of the &lt;a href="https://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv-utils.git;a=summary"&gt;userv utilities&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It allows safe delegation of network routing to unprivileged users. The delegation is of a specific address range, so different ranges can be delegated to different users, and the authorised user cannot interfere with other traffic.&lt;/p&gt;
&lt;p&gt;This is used in the default configuration of hippotat packages, so that an ordinary user can start up the hippotat client as needed.&lt;/p&gt;
&lt;p&gt;On &lt;a href="https://www.chiark.greenend.org.uk/"&gt;chiark&lt;/a&gt; userv-ipif is used to delegate networking to users, including administrators of allied VPN realms. So chiark actually runs at least 4 VPN-ish systems in production: secnet, hippotat, &lt;a href="https://vox.distorted.org.uk/mdw/"&gt;Mark Wooding&lt;/a&gt;’s Tripe, and still a few links managed by the now-superseded &lt;code&gt;udptunnel&lt;/code&gt; system.&lt;/p&gt;
&lt;h2&gt;&lt;code&gt;userv&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;userv ipif&lt;/code&gt; is a userv service. That is, it is a facility which uses &lt;code&gt;userv&lt;/code&gt; to bridge a privilege boundary.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.chiark.greenend.org.uk/doc/userv/spec.html/"&gt;&lt;code&gt;userv&lt;/code&gt;&lt;/a&gt; is perhaps my most under-appreciated program. userv can be used to straightforwardly bridge (local) privilege boundaries on Unix systems.&lt;/p&gt;
&lt;p&gt;So for example it can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Allow a sysadmin to provide a shell script to be called by unprivileged users, but which will run as root. &lt;code&gt;sudo&lt;/code&gt; can do this too but it has quite a few gotchas, and you have to be quite careful how you use it - and its security record isn’t great either.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Form the internal boundary in a privilege-separated system service. So, for example, the &lt;code&gt;hippotat&lt;/code&gt; client is a program you can run from the command line as a normal user, if the relevant network addresses have been delegated to you. On chiark, CGI programs run as the providing user - not using &lt;code&gt;suexec&lt;/code&gt; (which I don’t trust), but via userv.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;userv services can be defined by the &lt;em&gt;called user&lt;/em&gt;, not only by the system administrator. This allows a user to reconfigure or divert a system-provided default implementation, and even allows users to define and implement ad-hoc services of their own. (Although, the system administrator can override user config.)&lt;/p&gt;
&lt;h2&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;Thanks for the help I had in this effort.&lt;/p&gt;
&lt;p&gt;In particular, thanks to Sean Whitton for encouragement, and the ftpmaster review; and to the Debian Rust Team for their help navigating the complexities of handling Rust packages within the Debian Rust Team workflow.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=14161" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2009-05-21:377446:13884</id>
    <link rel="alternate" type="text/html" href="https://diziet.dreamwidth.org/13884.html"/>
    <link rel="self" type="text/xml" href="https://diziet.dreamwidth.org/data/atom/?itemid=13884"/>
    <title>Rust for the Polyglot Programmer, December 2022 edition</title>
    <published>2022-12-20T01:23:21Z</published>
    <updated>2022-12-20T01:47:52Z</updated>
    <category term="rust-polyglot"/>
    <category term="computers"/>
    <category term="rust"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">&lt;p&gt;I have reviewed, updated and revised my short book about the Rust programming language, &lt;a href="https://www.chiark.greenend.org.uk/~ianmdlvl/rust-polyglot/"&gt;Rust for the Polyglot Programmer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It now covers some language improvements from the past year (noting which versions of Rust they’re available in), and has been updated for changes in the Rust library ecosystem.&lt;/p&gt;
&lt;p&gt;With (further) assistance from Mark Wooding, there is also a new &lt;a href="https://www.chiark.greenend.org.uk/%7Eianmdlvl/rust-polyglot/safety.html#integers-conversion-checking"&gt;table of recommendations for numerical conversion&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Recap about Rust for the Polyglot Programmer&lt;/h3&gt;
&lt;p&gt;There are many introductory materials about Rust. This one is rather different. Compared to much other information about Rust, Rust for the Polyglot Programmer is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dense: I assume a lot of starting knowledge. Or to look at it another way: I expect my reader to be able to look up and digest non-Rust-specific words or concepts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Broad: I cover not just the language and tools, but also the library ecosystem, development approach, community ideology, and so on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Frank: much material about Rust has a tendency to gloss over or minimise the bad parts. I don’t do that. That also frees me to talk about strategies for dealing with the bad parts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Non-neutral: I’m not afraid to recommend particular libraries, for example. I’m not afraid to extol Rust’s virtues in the areas where it does well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terse, and sometimes shallow: I often gloss over what I see as unimportant or fiddly details; instead I provide links to appropriate reference materials.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After reading Rust for the Polyglot Programmer, you won’t know everything you need to know to use Rust for any project, but should know where to find it.&lt;/p&gt;
&lt;p&gt;Comments are welcome of course, via the Dreamwidth comments or &lt;a href="https://salsa.debian.org/iwj/rust-polyglot/"&gt;Salsa issue or MR&lt;/a&gt;. (If you’re making a contribution, please indicate your agreement with the &lt;a href="https://salsa.debian.org/iwj/rust-polyglot/-/raw/main/DEVELOPER-CERTIFICATE"&gt;Developer Certificate of Origin&lt;/a&gt;.)&lt;/p&gt;
&lt;address&gt;edited 2022-12-20 01:48 to fix a typo&lt;/address&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=diziet&amp;ditemid=13884" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
</feed>
