Expose promoted template content digests - #61
Conversation
The retry sweep ran at reapOnce's tail, so a failed reap commit skipped it; trigger it from the tick loop like retryRemovals. Reuse pinnedArchiveCks for the single-id check, skip the sweep scan when no markers exist, and tighten digest/store comments.
|
Before this ships: decide the digest stream format. cocoonstack/cocoon#193 proposes engine-side digest emission, which is only practical if the stream moves from the v1 single ordered stream to a v2 per-file manifest (per-file sha256 computed in write order, sorted manifest hashed last). The wire fields and sha256: prefix are unchanged either way, but the digest values differ - switching is free before the first release of this API and needs a version bump plus re-promotion afterwards. If v2 is agreed, the sandbox-side swap in exportContentDigest is small and also parallelizes the local fallback. |
A delete backlog re-checks every marker per tick; building the full pin map under m.mu for each one adds allocation and lock hold exactly when the store is already failing.
|
Format decision resolved: #64 replaces the v1 stream with a v2 chunked manifest (16 MiB chunks) computed by the store backends themselves - PublishDigested, dir parallel hash, s3 upload tee, digest moved out of meta.json. No compatibility kept; digest values change, which is why it lands before this API first ships. |
Summary
Integration
This closes the mutable-template identity gap identified while reviewing cocoonstack/instar#4 and the T11 item in cocoonstack/instar#1. Instar can pin and compare the digest returned by the exact Claim generation instead of trusting a reusable template name.
Validation
Boundary
Existing templates have an empty digest until they are promoted again. Shared directory stores must provide cross-node POSIX flock, and S3 keeps superseded generations until Delete under the existing single-writer-per-id contract. This PR does not add a template registry, version API, or claim-time full rehash.