25. Editions, stability, publishing
Two of this chapter’s three subjects are not in this edition. An
edition key that changes how a package is compiled, and a standard
library on the page to depend on: this edition teaches neither. A
manifest’s edition key is real, per-package, and changes no
compilation. The compiler’s release archive does carry a standard
library now, as std/ beside wolf, and from it use std.io
resolves; but this book pins no standard library of its own, its
programs import none, and the interpreter unpacked from its own archive
answers unsupported for the same line. §25.1 and §25.2 are reserved
for those mechanisms, and their pages are not written.
The third subject is written, because the toolchain carries it. wolf publish is the last verb in the story chapters 23 and 24 tell, and
§25.3 is what it verifies, what it writes, and what the written record
proves.
25.3 Publishing
den/logsearch has been ours since chapter 23: a manifest anyone can
read, a dependency it names, a ledger that witnesses both. The one
thing nobody else can do with it is depend on it, because the package
exists only where it was written. Publishing fixes that, and the verb
does not upload anything. It writes down what the package is:
$ wolf publish --dir app
den/logsearch@0.1.0 tree=b3:f8ce5f5b7ea6bb1b367c55b39e00b55c19086f035fc38866b8ede419e9523039 manifest=b3:d932b3c6008a901a5dc0135b1f816183d0b0abd881a2a82eb5acf8323ae1e8e7 interface=b3:97e6cc1775a06408de831a74ff9ae60abab22e13eda2e5d048de74a1b3623c35
wolf publish: record written to app/.wolf-publish/den-logsearch-at-0.1.0.record — submit it to your log's maintainer
The first line is the record, whole. den/logsearch@0.1.0 is its key:
a scoped name at one version, because every name has an owner (§23.1)
and a version is the unit of publication. The three addresses after it
are b3: digests (§23.3’s kind), and each pins a surface an earlier
chapter taught:
tree=is the content address of the package’s source files, the same source-filtered digest §23.3’s ledger records. It pins the code.manifest=is the address ofwolf.pkgitself: the dependencies, and the capability listwolf auditreads (§24.3). It pins the claims.interface=is the address of the package’spubsurface, the hash §22.2 printed withwolf interface. It pins the contract.
A published version is those three numbers under that key. Anything
answering to den/logsearch@0.1.0 whose tree, manifest, or interface
hashes differently is not the package, whatever it calls itself; the
check needs no trust in any server, because a digest can be recomputed
from the bits by anyone holding them.
A record is worth exactly what was checked before it was written, so
wolf publish verifies first: the package must resolve in full, and
the capability gate from §24.3 runs on it. A package whose code
reaches authority its manifest does not declare draws E1504 at
publish, and publishes nothing. The audit tree other people will
trust begins with a package that verified.
The transcript’s last line hands the record to somebody, and that
somebody keeps the transparency log: an append-only file of these
records, one line per published version, with a head beside it that is
re-derived on every append (a Merkle root over the whole file, under
the maintainer’s key, so a tampered mirror cannot pass for the log it
mirrors). wolf publish is the maintainer’s tool as well. Pointed at
a log directory and a key, it appends and re-signs:
$ wolf publish --dir app --log registry --key log.key
wolf publish: den/logsearch@0.1.0 appended (log size 1, head signed)
$ wolf publish --dir app --log registry --key log.key
wolf publish: `den/logsearch@0.1.0` is already in the log — a published version is immutable (the log is append-only)
$ echo $?
1
The refusal is the log’s whole character, and it is aimed at the
author first. No verb swaps the bits under a published version and no
verb removes one: the file only grows. §23.3 showed a moved tag
breaking one consumer’s build against a private witness; the log is
the same witness made public, so what den/logsearch@0.1.0 is
stopped being its author’s to change the moment the head was signed.
Availability is the easier half: any copy of the bits that matches the
tree address is the package, from any mirror, with nothing about the
mirror trusted.
§22.2 closed by promising that this chapter spends the export hash on
semantic versioning, and the spending is the third field. A release’s
pub surface is part of its published identity, so “this patch
changes nothing for importers” is a claim with an address attached,
and an attached address can be checked: fetch the two trees, run wolf interface on each, and compare what moved. Semver with teeth is that
check: not a promise in release notes, an arithmetic fact about two
lines of an append-only file.
Chapter 24 named three attack surfaces (distribution, execution, concealment) and spent itself on execution. The record is the covenant working at distribution: the manifest cannot ask for execution, code cannot exceed the authority the manifest declares, and a published version cannot quietly become a different one between the author’s machine and yours. What remains on faith is what no registry can verify and this design does not pretend to: whether the code is any good.
What you take on is still verified where chapter 23 put it (at wolf add, against the ledger); a registry client that browses, searches,
or fetches owner/pkg by name is not in this edition’s toolchain.