Finalise a staged upload into custody
Writes the staged octets at their no-overwrite content address — <tenant_id>/<digest_profile>/<byte_digest> — then reads them back out of the store and hashes them a second time.
RECORDS that MeshQu holds these exact octets under this tenant, and that the bytes the store returned hash to the digest they were written under.
PROVES byte identity of what was stored against what was sent. It proves nothing about the source: not that it is authentic, not that the locator ever served it, not that it is the right source for the policy.
FINALISED IS NOT SEALED. A finalised object that no sealed review submission references is an ORPHAN, and bounded reconciliation will collect it. Sealing is a separate transaction on the review-submission route.
If the object already exists at that address, it is reused only after tenant, digest profile, byte length AND the stored octets themselves all agree. Equal digests with unequal bytes is reported as a conflict and nothing is overwritten — there is no code path in this API that writes over a finalised object.
A read-back failure returns 500 and finalises nothing: a store that does not return what it was given is a server fault, not a caller error.
Authorizations
MeshQu API key passed as a bearer token: Authorization: Bearer mqu_…. Mint one in the console (Settings → API keys).
Tenant UUID for multi-tenant isolation. Required on all authenticated routes — validated before authentication (middleware/tenant.ts), so a missing or non-UUID header returns 400 (MISSING_TENANT_ID / INVALID_TENANT_ID) before the API key is checked.