Append one authoring feedback telemetry entry
Appends one observation about a model-proposed candidate rule: the proposal, the correction or rejection, and the reason.
RECORDS what a model proposed for one stable candidate, what a person corrected or rejected, the reason from a closed vocabulary, and — where the observation was made against a sealed subject — exactly which subject and optionally which recorded human finding it corresponds to.
PROVES only that the observation was appended, by a principal holding policies:write in this tenant. This is telemetry, not governance evidence. Appending here establishes nothing about whether anyone examined the candidate, nothing about the candidate’s status or authority, and nothing that any verification path consults: no row, label or count this endpoint produces is read by any check anywhere in the platform. Ruling B6 also keeps this material outside the sealed review package by construction — anything a reviewer relies on has to be copied into a new sealed component with its own identity, under that component’s own retention term.
Append-only. There is no update path and no delete path at any URL. Rows are removed only when their retention period has elapsed, by a retention function that runs outside the request path.
Links must resolve exactly. A review_record_id must name a recorded human review of the SAME sealed subject — a record about a different submission, revision or package digest is refused with 409 — and a review_finding_id must name an item that exists inside that record, or the request is a 422.
Retention. Each row stores the tenant period in force when it was created, in days. Effective retention is the SHORTER of that period and the tenant’s current one, so shortening the tenant period brings existing rows forward and lengthening it never extends them. The period is a tenant setting changed only by a verified human principal.
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.
Body
One appended telemetry observation about one model-proposed candidate. TELEMETRY, NOT GOVERNANCE EVIDENCE.
One appended telemetry observation about one model-proposed candidate. TELEMETRY, NOT GOVERNANCE EVIDENCE.
The STABLE candidate identity — the proposal id minted by the editor at the moment the model answered. This is the join key. Rule code is display identity and is recorded separately: a rename moves the code and would re-point every row filed under it.
1 - 200^[A-Za-z0-9._:-]{1,200}$Which subject the observation was made against. SEALED_SUBMISSION requires submission_id, candidate_revision and review_package_digest together (the ruling B1 currentness triple). PRE_SUBMISSION_DRAFT forbids all three AND forbids a review-record link, because a recorded human judgment exists only against a sealed subject. Absence is spelled as a value, not inferred from nulls.
SEALED_SUBMISSION What the person did to the proposal: changed it (CORRECTION) or removed it (REJECTION). There is no ACCEPTED value — this store records corrections and rejections, and a row asserting acceptance would be one step from reading as an approval.
CORRECTION Why the proposal was corrected or rejected, from a CLOSED vocabulary. An unknown value is refused with 400, and there is deliberately no OTHER: an open residual would make the vocabulary a suggestion and the distribution meaningless.
SOURCE_FIDELITY (the proposal misstates the source) and UNSUPPORTED_SEMANTICS (the product cannot express what the source requires) are kept distinct because one is fixed by re-reading the source and the other by changing the product.
SOURCE_FIDELITY What the model proposed, verbatim. Stored as evidence of what was said; the server never acts on it, re-runs it or checks it against anything.
The rule code as it stood. Display only; never a join key.
1 - 200Leg one of the sealed subject. Required when subject_kind is SEALED_SUBMISSION, forbidden otherwise.
Leg two of the sealed subject.
x >= 1Leg three of the sealed subject.
^[0-9a-f]{64}$The recorded human review (PWB-022b) this correction corresponds to. Bound by a five-column foreign key to a record written against THIS EXACT sealed subject, so a row naming a record about a different submission, revision or package digest is refused at the database as well as at the route.
One item id inside that record's findings or corrections. It must RESOLVE: an id naming no item in that record is refused, at the route and by a database trigger, because findings are JSON array elements that no foreign key can reach.
1 - 200^[A-Za-z0-9._:-]{1,200}$The correction or rejection text, verbatim. Optional: a rejection with no stated text is a real thing a person does, and a placeholder would put words in their mouth.
1 - 8000Response
One appended telemetry row. RECORDS what a model proposed and what a person corrected or rejected. PROVES only that the observation was appended.
One appended telemetry row. RECORDS what a model proposed and what a person corrected or rejected. PROVES only that the observation was appended.
Which subject the observation was made against. SEALED_SUBMISSION requires submission_id, candidate_revision and review_package_digest together (the ruling B1 currentness triple). PRE_SUBMISSION_DRAFT forbids all three AND forbids a review-record link, because a recorded human judgment exists only against a sealed subject. Absence is spelled as a value, not inferred from nulls.
SEALED_SUBMISSION What the person did to the proposal: changed it (CORRECTION) or removed it (REJECTION). There is no ACCEPTED value — this store records corrections and rejections, and a row asserting acceptance would be one step from reading as an approval.
CORRECTION Why the proposal was corrected or rejected, from a CLOSED vocabulary. An unknown value is refused with 400, and there is deliberately no OTHER: an open residual would make the vocabulary a suggestion and the distribution meaningless.
SOURCE_FIDELITY (the proposal misstates the source) and UNSUPPORTED_SEMANTICS (the product cannot express what the source requires) are kept distinct because one is fixed by re-reading the source and the other by changing the product.
SOURCE_FIDELITY The tenant retention period in force when this row was created, in DAYS. Stored so a later lengthening of the tenant period cannot extend what was collected under a shorter one. Effective expiry is created_at + min(this, the tenant's current period) and is derived, never stored.
30 <= x <= 730