Record a human review of a sealed review submission
Persists one named human’s findings, corrections and package-level disposition, bound to the exact sealed subject named by the path submission id together with expected_candidate_revision and expected_review_package_digest.
RECORDS that one named human wrote these findings, these corrections and this one package-level disposition against this exact sealed subject, at this time.
PROVES that the record names that subject. Nothing more. This is research evidence, not approval: it does not establish that the policy is correct, ratified, approved, activated or verified; that the source is true or complete; or that the reviewer was competent, independent or unblinded. Ruling B5 keeps this wave review-only.
Requires a verified human-session principal. An API-key principal receives 403 HUMAN_PRINCIPAL_REQUIRED — the same route class as POST /v1/policies/{id}/versions/{version}/reject (ruling D3a). A machine cannot record that a human reviewed something.
A STOP disposition does NOT call the reject route. POST /v1/policies/{id}/versions/{version}/reject transitions a submitted version back to draft and is a separate human governance act; this route calls it under no disposition. Recording a judgment and performing an act are different things, and only the second moves a policy version.
A stale subject is refused, never silently re-pointed. If the expected revision or digest disagrees with the sealed row the response is 409 with a code naming THAT leg (CANDIDATE_REVISION_MISMATCH, REVIEW_PACKAGE_DIGEST_MISMATCH), because a judgment recorded against one sealed subject can never be applied to another.
Immutable once written. There is no edit path and no erasure path. A reviewer who changes their mind records a NEW judgment, and the earlier one stays legible.
This route ratifies nothing, activates nothing and records no decision. It is not a receipt and no receipt binds its output.
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.
Path Parameters
Policy id. The submission must belong to it, or the request is a 404.
The sealed submission the judgment is recorded against. This is the review IDENTITY — not the policy version, which is a mutable container that yields many sealed subjects over time.
Body
One named human's judgment of one exact sealed subject. The two expected_* fields are the reviewer's assertion of WHICH subject they read; the server compares them against the sealed row and refuses a disagreement rather than recording the judgment against whatever is current.
One named human's judgment of one exact sealed subject. The two expected_* fields are the reviewer's assertion of WHICH subject they read; the server compares them against the sealed row and refuses a disagreement rather than recording the judgment against whatever is current.
The candidate revision the reviewer believes they judged. Compared against the sealed subject; a disagreement is 409 CANDIDATE_REVISION_MISMATCH, never a silently corrected value.
x >= 1The package digest the reviewer believes they judged. A disagreement is 409 REVIEW_PACKAGE_DIGEST_MISMATCH.
^[0-9a-f]{64}$What the reviewer found. May be empty — "I found nothing" is a real result and the protocol scores it, so an empty array is recorded rather than refused.
500What the reviewer would change, each with a proposal or explicit uncertainty.
500The reviewer's ONE package-level judgment, spelled as the preregistered protocol spells it: ACCEPT, CORRECT_AND_RESUBMIT, STOP.
None of the three is an approval. ACCEPT is the protocol's word for "one reviewer found no material defect in this package" — a statement about a reading, not about the candidate's authority. Ruling B5 keeps this beta review-only, which is why no value here names ratification.
STOP does not call the reject route. POST /v1/policies/{id}/versions/{version}/reject is a separate human governance act (ruling D3a) that transitions a version's status. Recording STOP records a judgment and moves nothing.
ACCEPT Response
A persisted human review record. RECORDS one named human's findings, corrections and package-level disposition against one exact sealed subject. PROVES that the record names that subject — and nothing further. Research evidence, not approval.
A persisted human review record. RECORDS one named human's findings, corrections and package-level disposition against one exact sealed subject. PROVES that the record names that subject — and nothing further. Research evidence, not approval.
Leg one of the three that identify the sealed subject this record names.
Leg two.
x >= 1Leg three, under meshqu-review-package/v1.
^[0-9a-f]{64}$The STABLE identity of the reviewer (user:<uuid> for a verified human session). Records attribution; proves nothing about competence, independence or that the person read anything. Compare on this, never on the display name.
The reviewer's attribution as it stood when the record was written. MUTABLE by nature — legible, never an identity.
The reviewer's ONE package-level judgment, spelled as the preregistered protocol spells it: ACCEPT, CORRECT_AND_RESUBMIT, STOP.
None of the three is an approval. ACCEPT is the protocol's word for "one reviewer found no material defect in this package" — a statement about a reading, not about the candidate's authority. Ruling B5 keeps this beta review-only, which is why no value here names ratification.
STOP does not call the reject route. POST /v1/policies/{id}/versions/{version}/reject is a separate human governance act (ruling D3a) that transitions a version's status. Recording STOP records a judgment and moves nothing.
ACCEPT