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 of wolf.pkg itself: the dependencies, and the capability list wolf audit reads (§24.3). It pins the claims.
  • interface= is the address of the package’s pub surface, the hash §22.2 printed with wolf 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.