“Shipped” is one of the most overloaded words in software.
It can mean the source compiles. It can mean a signed app exists on one machine. It can mean Apple notarized a binary. It can mean an archive reached storage, a download URL returns 200, a version is live on the App Store, or a replacement build has merely entered review.
Those states are related, but they are not interchangeable. Once a company maintains several native applications, the release lane stops being a collection of shell commands. It becomes a product with inputs, contracts, state transitions, tests, receipts, and failure recovery.
That is the role of BlackLabel Ship. It is internal tooling, not a standalone offer. Its user is the engineering organization, and its output is not “a successful command.” Its output is a verifiable relationship between source, packaged bytes, approval, platform state, and the artifact a buyer can actually retrieve.
Start with an app contract
Each application enters the lane through a configuration contract. The contract names the source repository, bundle identifier, app name, build command, built-app location, required architecture, required and forbidden entitlements, patterns that must not appear inside the bundle, storage keys, update-manifest endpoint, and public download URL.
This matters because release assumptions otherwise live in operator memory. One app may need a universal binary; another may require a specific entitlement; every buyer-facing bundle must exclude internal databases, tokens, personal information, and company data. A machine-readable contract turns those differences into reviewable inputs.
The release spine then applies shared invariants. It packages without AppleDouble sidecars. It signs after all bundle mutations. It submits for notarization, validates the staple, uploads the artifact, downloads it again from the public path, compares hashes, applies a Gatekeeper check to the downloaded copy, updates the manifest only after the live gate succeeds, and appends a ship record.
No single step proves the whole release. Together, the steps form a chain of custody.
The commit must travel with the bytes
A July failure exposed the most important gap in that chain.
A Sovereign artifact had been built and staged. More commits landed in the repository before publication. At publish time, the lane asked Git for the current HEAD and wrote that newer commit into the ledger. Notarization, stapling, hash checks, and Gatekeeper all passed because they were checking a valid artifact. The problem was that nothing connected the commit written into the record to the bytes that had been built hours earlier.
The ledger therefore attributed changes to a binary that did not contain them.
The correction was architectural. At build time, the lane now writes provenance beside the staged application: the source commit and a hash of the executable. At publish time, it reads that staged provenance and re-hashes the executable. An unstamped artifact is refused. A changed executable is refused. A source tree that moves during the build is refused. The publish path no longer asks the repository what commit happens to be current.
The provenance file sits beside the signed bundle rather than inside it, because changing the contents after signing would break the seal. That small placement detail captures the larger idea: provenance must be bound early enough to describe the artifact and stored in a way that does not invalidate it.
Approval belongs in the lane
The same review found that the final release decision existed in company policy but not in executable enforcement. A written rule saying “the founder approves publication” is useful governance. It is not a release gate.
The lane added an explicit founder-GO requirement. Absence means refusal, not implied permission. It also added a build-number gate after a live case showed how a new binary could retain an already-shipped build number. That error is especially dangerous when an updater uses the build number to decide whether existing users are current: new code can be published while every installed app is told there is nothing to download.
The rule is now precise. The same bytes may resume a failed publication under the same build identity. Different bytes may not reuse an already-shipped build number.
Rehearsal was separated from publication as well. Dry runs had previously written into the ship-of-record, making the ledger require cleanup after tests. The corrected lane writes rehearsals to a different file. A production ledger should not need interpretation to determine whether a row describes a real release.
A receipt is a status, not a marketing claim
By July 7, the ship ledger contained non-rehearsal notarization records for nine distinct applications. That statement means exactly what it says: nine application identities had notarized artifacts recorded in the internal release ledger.
It does not mean nine apps were live on the App Store.
The August 1 truth audit verified four live App Store applications through Apple lookup evidence: Black Label Real Estate, BLVigil, Black Label Academy, and Black Label Marketing. On August 2, the replacement-build audit recorded the current submitted builds as processed VALID by Apple and in WAITING_FOR_REVIEW, while BLVigil's macOS record was READY_FOR_SALE. A pending replacement should not be described as the live version before approval.
Distribution proof also does not override product policy. Marketing remains on promotional hold despite its historical release evidence. Leads remains retired even though the ledger contains historical artifacts. Circuit is off sale. Trading's signed or notarized state supports distribution claims, not win-rate, profit, return, edge, track-record, or auto-trading claims.
The release system proves what reached a release state. It does not grant permission to infer customer outcomes.
Build the release lane like buyers depend on it
A mature release lane needs the same properties expected from a buyer-facing product:
- explicit inputs rather than tribal knowledge;
- fail-closed validation rather than optimistic defaults;
- observable state transitions rather than a single success message;
- stable identities for builds and artifacts;
- tests that reproduce known failure shapes;
- append-only receipts plus a correction mechanism;
- separation between rehearsal and production;
- public readback from the channel a buyer actually uses.
It also needs honest status language. “Built,” “signed,” “notarized,” “downloadable,” “submitted,” “waiting for review,” and “ready for sale” are not stylistic variations. They are distinct states backed by different authorities.
Treating release engineering as a product does not make shipping slower. It reduces the time spent answering the worst possible question after a release: what exactly did we send, and can we prove it?
Top comments (0)