Template: creative approval
(needs modelrig 0.12.0 or newer) Approve or reject generated images, video and audio the way a creative lead reviews a batch: on brief, safe for your brand, any text legible, no visible generation defects, and usable without another round. This page is one of the use-case templates — a starting point, not a finished grader. Unlike the text templates, the thing being judged is a generated asset: an artifact of type image/, video/ or audio/* saved in the step whose rig.recordCall({ ..., units }) made it. The machine-readable source is node_modules/modelrig/templates/creative-approval.json.
Does this task fit?
Creative approval fits the shipped loop when four conditions hold. (1) Each generation call is recorded with rig.recordCall({ ..., units }) — images, seconds or characters — so it is priced per unit from a sourced rate (or flagged unpriced, never guessed), and each asset it produced is saved as an artifact of type image/, video/ or audio/* in the same step. (2) Someone on your creative team can write down what on brief and on brand mean for your work, which is the grading guide below. (3) That person approves or rejects assets in the Grade queue's Media approval tab, so the approval rate per dollar on Costs is measured from real verdicts; it is withheld until a model has ten approvals. (4) You accept that generated media is stored UNSCREENED: ModelRig's PII/PHI scrub reads text only, so do not generate or store images of real people's documents or other regulated content through it. There is no automated image scoring in this template; the verdicts are human. It is a starting point, not a claim that any model produces usable creative — fill in your brief and brand rules before you rely on it.
Starter schema
Replace every TODO with your own taxonomy; the enum slots ship without values on purpose, so an unfilled template refuses to look finished.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$comment": "STARTER SCHEMA for the RECORD of one generated asset (the brief and what was produced), not for the media bytes themselves — the asset is saved as its own image/*, video/* or audio/* artifact. Replace every TODO with your own values before use. The template runs as-is: free-text fields validate immediately.",
"title": "CreativeAsset",
"type": "object",
"additionalProperties": false,
"required": [
"brief",
"format",
"asset_artifact_id"
],
"properties": {
"brief": {
"type": "string",
"description": "The creative brief or prompt the asset was generated from — what the reviewer checks on-brief against."
},
"format": {
"type": "string",
"description": "The placement the asset is for (a hero banner, a social square, a voice-over). TODO(enum): constrain this to YOUR own placement names by adding an \"enum\": [ ... ] here. It runs as free text immediately.",
"$comment": "TODO(enum): add your placement names as the enum for this field."
},
"asset_artifact_id": {
"type": "string",
"description": "The id of the image/video/audio artifact this record describes (the handle rig.artifacts.save returned)."
},
"required_text": {
"type": "string",
"description": "Optional: any words that must appear in the asset exactly (a headline, a product name), so legibility can be checked against them."
}
}
}
Starter grading guide
The starter criteria run as written — sharpen each one in your team's own words as you grade. They are in the exact jsonb shape the set_task_settings write path validates — binary checks, each with a one-sentence pass and fail. There is no pass_threshold here: that lives in the route's grade: block.
on_brief — Matches the brief
- Pass: the asset shows what the brief asked for — subject, setting, mood and placement — without the reviewer having to squint or explain it away.
- Fail: The asset misses or contradicts the brief: the wrong subject, a missing element the brief named, or a mood the brief ruled out.
brand_safe — Safe for your brand
- Pass: nothing in the asset conflicts with your brand rules: colours, logo use, imagery you avoid, and anything that could embarrass the brand or offend its audience.
- Fail: The asset breaks a brand rule, misuses a logo or trademark, or includes imagery your brand would not publish.
legible_text — Any text is legible and correct
- Pass: every word that appears in the asset is spelled correctly, readable at the placement's size, and matches the required text exactly when there is one.
- Fail: Text in the asset is garbled, misspelled, unreadable at size, or differs from the required text.
no_artifacts — No visible generation defects
- Pass: the asset has no obvious generation defects: anatomy, hands, faces and objects look right, edges are clean, and audio or video has no glitches.
- Fail: The asset shows a visible defect — extra or fused fingers, warped faces or objects, smeared edges, audio clicks, or video flicker — that a viewer would notice.
usable_as_is — Usable without another round
- Pass: the asset could ship in its placement as it is, or with a trim or crop at most.
- Fail: The asset needs a regeneration or real retouching before it could be used.
The guide's escalation band starts at epsilon: 0.1: a grade within that distance of the route's pass threshold is treated as judge-uncertain and sent to a human. It is a starting band — tune it as your grader calibrates.
Golden checklist
Roughly twenty examples that cover:
- One clearly approved asset per placement you generate for — the ordinary case your team signs off every week.
- An asset that is beautiful but off-brief, so the guide learns that quality does not excuse a missed brief.
- An asset with text in it: one where the words are exactly right, and one with a single misspelled or garbled word.
- An asset with a subtle generation defect (a hand, an edge, a reflection) that a quick glance misses.
- An asset that breaks one of your brand rules while looking fine otherwise.
- An asset that needed only a crop (usable as is) next to one that needed a regeneration.
- Aim for roughly twenty goldens total, weighted toward the borderline cases above rather than the obvious approvals.
Escalation starter
Start by sending to a second reviewer every asset destined for a paid or high-visibility placement, every asset with text in it, and every asset a reviewer approved with a comment. The machine-side band lives in starter_guide.escalation.epsilon: a grade within that distance of your task's pass threshold is treated as grader-uncertain and sent to the human queue. The 0.1 here is a starting band — widen it while you build trust, narrow it as your grader calibrates.
Using it
By hand: record each generation call with its units — rig.recordCall({ provider, model, usage: { tokensIn: 0, tokensOut: 0 }, units: { images: 4 }, latencyMs, stepKey: "hero" }) — and save each asset it produced with rig.artifacts.save(bytes, { name, type: "image/png", stepKey: "hero" }). Write the starter criteria into your team's own words, then approve or reject the assets in the console (Grade queue → Media approval). Costs shows the approval rate per $ by model once a model has ten approvals; below that the rates are withheld and the reason is shown. Generated media is stored unscreened — the PII/PHI scrub reads text only, and the console says so on every asset.
From a coding agent: set_task_settings (the task-settings scope) authors the grading guide as-is. There is no automated image scoring here: the verdicts are human. See the use-case templates overview for the full two-path walkthrough.