SAPE-10 taught the codebase to seal and verify an operation bundle. It did
that inside internal/bundle, where only Go code can reach it. Nothing in the shipped
binary could act on a bundle, so the signing work was real and entirely unreachable — an operator
handed a signed bundle had no command to run.
That is the gap SAPE-12 kept walking into. A worked external operation, published as a challenge to a stranger, needs a stranger-usable path from file to installed. This ticket is that path.
Two commands. sapedb verify FILE is standalone: no database, no lock, no secret, no
network. It prints four rows and refuses each of them separately, so an operator can tell
never signed from signed, then changed from signed by a stranger — three
situations that demand three different responses and that a single "invalid bundle" would have
flattened into one.
read yes sapedb/bundle:v1
signed yes ed25519, key 66be7e33…0c473a
intact no these are not the declarations that key signed
trusted - not reached; the signature did not check out
The report is printed on refusal too, and it prints what the bundle declares under a heading that says nothing below it is vouched for. A reader deciding whether a file is worth chasing the author about needs to see the contents even when — especially when — the checks failed.
It also prints two names side by side, which is the part worth slowing down for:
says it is "Ledger Authors" (the bundle's own claim about its author)
known as "north-star" (what an operator of this server called that key)
The first is signed but self-asserted: a bundle can claim any author it likes. The second is what somebody on this server wrote next to that key. Showing only the first would let a bundle name itself trustworthy.
sapedb install FILE runs the whole verification before it opens anything, so a bundle
nobody trusts leaves no .lock, no account folder and no empty database behind. Five
tests assert the directory is byte-for-byte unchanged after a refusal.
An operator names trusted signers in one environment variable, SAPEDB_TRUST, as
label=key entries separated by a comma or a newline — a shell writes one line,
a systemd EnvironmentFile may not, and an operator should not have to know which the
parser wanted.
There is no spelling of that variable that means "trust anything." The only shape
the parser accepts is 64 lower-case hex characters, so *, any=any and
everyone=* are each either an empty list or a refusal — and an empty list refuses every
bundle rather than permitting one. A test pins exactly that, by name. A malformed list is
refused rather than treated as empty, because an operator who mistyped a key must not be sent off to
write a list they already wrote.
One label over two keys is refused as well. The label is what verify prints and what the
change log records; one label naming two keys makes both of those say something untrue.
1 declare | bundle "ledger-pack" "2.1.0" signed by 66be7e33…0c473a, trusted here as "north-star"
Not the account that ran the command. Four parts, each answering a different question: the key in full (the identity, and the only fact on this path that anything actually checked — truncated, it could not be compared against a trust list), the operator's label at the time (a later rename of the trust list does not rewrite history, which is correct), and the bundle's own name and version (self-asserted, signed, and what an author will quote back at you).
A refused install rolls back explicitly instead of leaning on the process exiting and the pager
closing an uncommitted transaction. That distinction sounds academic until you notice that
apply() can lean on it — apply() is the process — while a caller
holding the same open store afterwards would be handed collections that are in the tree and will
never be committed.
The load-bearing part: the process-level test stays green when that rollback is deleted. One test would therefore have been a guard nobody had ever watched fail. So there are two, and the second one exists only because the first was measured to be blind to this.
This work came back labelled SAPE-11, which is a different ticket that had already shipped. The label was corrected before the merge and the number allocated here. It is a small thing, and it is the same family as everything else on this board: a name is not a measurement, and the only way to find out which ticket a diff belongs to is to read the diff.
go build ./..., go vet ./... and gofmt -l . clean on the
merged tree.go test ./... -count=1 green: all 20 packages ok.go test ./... -race -count=1 exits 0 with no FAIL.--- PASS lines including subtests, on
bce1c17 with a clean tree.bundle.Seal. This is why SAPE-12 is still open, and a
sealing command is being built now.bundle_* refusal codes are not reachable over the wire. Installing over the
wire is out of scope for 1.0.0; the trust parser is shaped so the daemon can pick it up unchanged.