Create or replace one of your draft review findings
Saves one working note under a client-issued id, bound to the exact sealed subject named by the path submission together with expected_candidate_revision and expected_review_package_digest.
RECORDS what one human reviewer has typed about this exact sealed subject and has NOT yet recorded.
DOES NOT ESTABLISH anything: not that the reviewer read the package, not that the note is right, not that the policy is correct, and not that the source is true or complete. A draft finding is a working note, not evidence — it is excluded from every digest, every receipt, every export and every research record, and no receipt binds one. A judgment becomes evidence only when its author submits a review record through the unchanged review-record route.
Your own notes only. A co-reviewer on the same submission never sees them, because showing one reviewer another’s working notes would pre-load the second reader. Naming another reviewer’s note returns 404 rather than 403: 403 would confirm that it exists.
Requires an authenticated human-session principal. An API-key principal that holds the policies:read or policies:write scope this route declares is refused 403 HUMAN_PRINCIPAL_REQUIRED at the handler; one lacking that scope is refused 403 FORBIDDEN one step earlier, by the scope gate. A machine has no working notes on a human review. This route is deliberately NOT in the humanGovernanceAct class that gates reject and ratification: a note is not a governance act, nothing transitions and nothing is recorded.
A note cannot be born stale. If the expected revision or digest disagrees with the sealed row the response is 409 naming THAT leg (CANDIDATE_REVISION_MISMATCH, REVIEW_PACKAGE_DIGEST_MISMATCH) — the same check, through the same comparison, that the review-record route makes, so this surface cannot become a way around it. The stored legs are the SEALED values, never the body’s.
A consumed draft id may never come back to life. Once a review record has consumed this exact id for this owner on this submission (POST …/consume, contract §5(a)), the id is retired: a later PUT naming it is refused 409 DRAFT_ID_CONSUMED, naming the consuming record. This is what keeps a replayed (or merely late) consume call from ever deleting a DIFFERENT note than the one it named — consumeForRecord deletes by (tenant, submission, owner, id) alone and has no memory of what it has already removed, so without this refusal the id would be free for a brand new, unrelated draft the moment it was consumed.
The location must resolve inside the sealed subject. A candidate_rule code that is not in the sealed candidate_policy, or a source_unit whose item or unit is not in the sealed source_manifest, is refused 422 — and so is a source_unit whose unit_id and source_item_id are each real but do not belong together (DRAFT_LOCATION_SOURCE_UNIT_ITEM_MISMATCH, naming both the supplied item id and the unit’s actual one). An example location is NOT resolved against the sealed case pack, and package needs no resolution.
Replacing a note keeps its first-written time. updated_at is the last save; there is no version history of a note, because the review record is the history.
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 note is about. This is the review IDENTITY — not the policy version, which is a mutable container that yields many sealed subjects over time.
The reviewer client's own handle for this note, in the same spelling a review record's item id uses. Client-issued: the server does not mint it, and it is unique only within one owner's notes on one subject. It is the SAME id the item will carry if the note is later recorded, so the link between a note and the item it became is legible without a pointer from the immutable side.
^[A-Za-z0-9._:-]{1,200}$Body
One working note, written by the human whose session carries this request. The owner is stamped from that session — there is no owner field here and a body carrying one is refused, because a note whose author could be chosen by the caller would be worth nothing as a private workspace.
One working note, written by the human whose session carries this request. The owner is stamped from that session — there is no owner field here and a body carrying one is refused, because a note whose author could be chosen by the caller would be worth nothing as a private workspace.
The candidate revision the reviewer believes they are writing about. Compared against the sealed subject; a disagreement is 409 CANDIDATE_REVISION_MISMATCH, never a silently corrected value — so a note cannot be born naming a subject that is already behind.
x >= 1The package digest the reviewer believes they are writing about. A disagreement is 409 REVIEW_PACKAGE_DIGEST_MISMATCH.
^[0-9a-f]{64}$Which of the two record lists this note is destined for. proposed belongs to a correction — but it is NOT required here, deliberately: a note is saved while it is still being typed, and refusing a half-written correction would lose the sentence the reviewer was in the middle of. The review-record route requires it at the moment the note is submitted, which is the moment it matters. Choosing a kind here commits the reviewer to nothing — nothing is recorded until they submit a review record.
finding Which slot of the sealed subject the note is filed against: one of the ten ruled component names (ruling B2), or package for an observation about the submission as a whole. Same closed set as a review record item, because a note becomes one.
source_manifest The reviewer's own materiality classification, from the preregistered protocol's scoring vocabulary. RECORDS the classification; establishes nothing about whether it is right — that comparison is the blinded run (PWB-026), not a working note.
MATERIAL Free text, stored exactly as typed. It is the reviewer's own working note, never an instruction the server acts on, and nothing reads it except its author.
1 - 4000Where in the sealed subject the note points (contract §3). The kind fixes which other fields carry meaning; a field belonging to another kind is ignored by the checks that kind does not run.
What the reviewer would put in its place, or their explicit uncertainty. Belongs to a correction.
1 - 4000The durable candidate-rule identity this note concerns (PWB-010), when the reviewer is working on one. Distinct from location.rule_code, which is the mutable code they clicked.
1 - 200Response
One durable working note. RECORDS what one reviewer typed about one exact sealed subject and has not recorded. DOES NOT ESTABLISH anything — not that they read anything, not that the note is right, and nothing whatever about the policy or the source. Not evidence, not a receipt field, excluded from every digest and export.
One durable working note. RECORDS what one reviewer typed about one exact sealed subject and has not recorded. DOES NOT ESTABLISH anything — not that they read anything, not that the note is right, and nothing whatever about the policy or the source. Not evidence, not a receipt field, excluded from every digest and export.
^[A-Za-z0-9._:-]{1,200}$Leg one of the subject.
Leg two, as SEALED.
x >= 1Leg three, as SEALED, under meshqu-review-package/v1.
^[0-9a-f]{64}$The stable identity of the human who wrote the note (user:<uuid>), stamped from their session. Nobody else reads this note — not a co-reviewer, not a tenant admin.
Which of the two record lists this note is destined for. proposed belongs to a correction — but it is NOT required here, deliberately: a note is saved while it is still being typed, and refusing a half-written correction would lose the sentence the reviewer was in the middle of. The review-record route requires it at the moment the note is submitted, which is the moment it matters. Choosing a kind here commits the reviewer to nothing — nothing is recorded until they submit a review record.
finding Which slot of the sealed subject the note is filed against: one of the ten ruled component names (ruling B2), or package for an observation about the submission as a whole. Same closed set as a review record item, because a note becomes one.
source_manifest The reviewer's own materiality classification, from the preregistered protocol's scoring vocabulary. RECORDS the classification; establishes nothing about whether it is right — that comparison is the blinded run (PWB-026), not a working note.
MATERIAL Free text, stored exactly as typed. It is the reviewer's own working note, never an instruction the server acts on, and nothing reads it except its author.
1 - 4000Where in the sealed subject the note points (contract §3). The kind fixes which other fields carry meaning; a field belonging to another kind is ignored by the checks that kind does not run.
The subject legs and location this note was carried FROM, when it was carried. RECORDS the carry; establishes nothing about the earlier reading applying to the new subject — it does not.
The last save. There is no version history of a note; a note is a note.
True when the sealed subject this note names is no longer the one in front of the reviewer. A stale note is KEPT and shown, and it cannot be carried into a review record — the record route runs its own three-leg check and refuses, which this surface does not weaken.
Which disagreement makes this note stale, when it is. Derived at read time against the live sealed row and never stored, so it cannot drift away from the truth. The first three name a leg of the subject identity; the last two name what happened to the subject itself.
subject_missing