Binding approval to a digest of an immutable revision is the right shape, and the point about not re-reading a mutable draft between the hash check and execution is the subtle part. One suggestion is to make the claim itself atomic, for example an UPDATE ... WHERE revision_id = approved AND status = 'approved' that flips the row to 'publishing' and checks the affected row count, so two workers cannot both execute the same approval. For canonicalization, json.dumps with sort_keys is fine inside one codebase, but if another service ever recomputes the digest, a spec like RFC 8785 (JCS) removes float and Unicode normalization ambiguity. Another question is whether the digest should also cover the schema version and the reviewer-visible rendering (for instance, the preview that was shown), since an approval is only meaningful relative to what the person actually saw. How would you handle media that is transformed by the platform after upload, where the fingerprint at execution can no longer match?
For platform-side transcoding, I would keep the approved input digest and the platform output as separate records: verify the exact bytes sent, then store the returned media/post ID and the checks performed on the published result. A re-encoded platform asset should not be expected to match the input hash.
The schema version is already in the sample manifest. A production review record could also identify the preview artifact and renderer version. The conditional claim you describe is useful for selecting one worker, but recovery after a worker dies still needs its own policy.
One JCS detail: RFC 8785 defines canonical serialization but explicitly preserves Unicode strings as-is; it does not normalize them. Any normalization policy should run before the preview and approval. These are extensions of the reference pattern, not claims about SMTasker's implementation.
Binding approval to a digest of an immutable revision is the right shape, and the point about not re-reading a mutable draft between the hash check and execution is the subtle part. One suggestion is to make the claim itself atomic, for example an UPDATE ... WHERE revision_id = approved AND status = 'approved' that flips the row to 'publishing' and checks the affected row count, so two workers cannot both execute the same approval. For canonicalization, json.dumps with sort_keys is fine inside one codebase, but if another service ever recomputes the digest, a spec like RFC 8785 (JCS) removes float and Unicode normalization ambiguity. Another question is whether the digest should also cover the schema version and the reviewer-visible rendering (for instance, the preview that was shown), since an approval is only meaningful relative to what the person actually saw. How would you handle media that is transformed by the platform after upload, where the fingerprint at execution can no longer match?