Skip to main content
POST
Carry one stale draft review finding to an explicit sealed subject

Authorizations

Authorization
string
header
required

MeshQu API key passed as a bearer token: Authorization: Bearer mqu_…. Mint one in the console (Settings → API keys).

X-MeshQu-Tenant-Id
string
header
required

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

id
string<uuid>
required

Policy id. The submission must belong to it, or the request is a 404.

submissionId
string<uuid>
required

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.

draftId
string
required

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.

Pattern: ^[A-Za-z0-9._:-]{1,200}$

Body

application/json

Names the sealed subject to carry one stale working note to. The reviewer chooses it from the sealed subjects of the same policy version — this route never defaults to the newest one on the caller's behalf.

Names the sealed subject to carry one stale working note to. The reviewer chooses it from the sealed subjects of the same policy version — this route never defaults to the newest one on the caller's behalf.

target_submission_id
string<uuid>
required

The sealed submission to carry this note to. Must be a DIFFERENT sealed submission of the SAME policy version as the note's own (stale) subject — never the path's own submission, which the request is refused 422 for naming. An id that does not resolve to a sealed submission of that policy and version is refused 404.

expected_candidate_revision
integer
required

The candidate revision the reviewer believes the TARGET carries, read from the list the console offered them. A disagreement with the target's actual sealed row is 409 CANDIDATE_REVISION_MISMATCH — the same stale-read protection the PUT route gives an ordinary save, so a target list fetched a moment too early cannot silently carry a note onto the wrong subject.

Required range: x >= 1
expected_review_package_digest
string
required

The package digest the reviewer believes the TARGET carries. A disagreement is 409 REVIEW_PACKAGE_DIGEST_MISMATCH.

Pattern: ^[0-9a-f]{64}$

Response

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.

id
string
required
Pattern: ^[A-Za-z0-9._:-]{1,200}$
tenant_id
string<uuid>
required
submission_id
string<uuid>
required

Leg one of the subject.

candidate_revision
integer
required

Leg two, as SEALED.

Required range: x >= 1
review_package_digest
string
required

Leg three, as SEALED, under meshqu-review-package/v1.

Pattern: ^[0-9a-f]{64}$
owner_principal
string
required

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.

kind
required

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.

Available options:
finding
slot
required

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.

Available options:
source_manifest
severity
required

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.

Available options:
MATERIAL
detail
string
required

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.

Required string length: 1 - 4000
proposed
string | null
required
candidate_rule_id
string | null
required
location
object
required

Where 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.

reassociated_from
object | null
required

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.

created_at
string<date-time>
required
updated_at
string<date-time>
required

The last save. There is no version history of a note; a note is a note.

stale
boolean
required

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.

stale_reason
required

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.

Available options:
subject_missing