Track · critic
Critic track
Cross-provider taste auditor. Evaluates generated output (illustrations, layouts, prose, scene compositions) against authoritative reference sets with weighted rubrics. By design the provider that critiques is independent from whatever generated — so a Claude-authored rig gets judged by GPT, or vice versa.
Endpoints
| Route | Auth | Purpose |
|---|---|---|
GET /api/v1/critic/rubrics | critic:v1:read | List every rubric (title, id, weight schema). |
GET /api/v1/critic/rubrics/[id] | critic:v1:read | One rubric's full definition. |
GET /api/v1/critic/references | critic:v1:read | List reference sets (labels, image counts). |
GET /api/v1/critic/references/[id] | critic:v1:read | One reference set's images + notes. |
POST /api/v1/critic/critique | critic:v1:use | Submit an output for scoring. Billable. |
:read is free (or plan-default). :use is metered.
Scopes
| Scope | Grants |
|---|---|
critic:v1 | Umbrella. Every endpoint above. |
critic:v1:read | Rubric + reference inspection. No critique calls. |
critic:v1:use | POST /critique. Implicitly grants :read. |
Quick critique
curl -X POST "https://urja.insightsbyomkar.com/api/v1/critic/critique" \
-H "x-api-key: $CRITIC_API_KEY" \
-H "content-type: application/json" \
-d '{
"rubric": "great-dane-construction",
"reference": "great-dane",
"target": { "svg": "<svg>…</svg>" },
"meta": { "iteration": 12, "hypothesis": "shorter muzzle" }
}'
Response:
{
"score": 7.2,
"perCriterion": [{ "name": "muzzle-skull-ratio", "score": 0.74, "weight": 0.15 }, ...],
"text": "Improved vs iter 11. Muzzle length closer to breed standard...",
"provider": "openai:gpt-4o",
"referenceUsed": "great-dane"
}
Cross-provider independence
The rubric evaluator lives in lib/critic/providers/. Environment config (CRITIC_DEFAULT_PROVIDER=openai|anthropic) picks the judge; the default provider for Urja today is OpenAI. Rotating to Anthropic is a per-customer tweak we route through at mint time or at request time via a header.
Reference sets
Every reference set is a public-domain, pre-1929 authoritative corpus. No modern Solar Fire / Rudhyar / Hand translations — rubric language cites only works whose copyright has lapsed. The intent is legal-clean AI grounding rather than taste-via-vibes.
Examples of shipped sets:
great-dane— breed-standard photos + anatomical plates (public domain).art-nouveau-ornaments— decorative motifs from c.1900–1920 prints.
Automatic runs (GitHub Actions)
The lucky-critique workflow in Urja runs scripts/critic/sweep-lucky.ts on every character-manifest change, posts a score table as a PR comment, and nightly-regresses against the great-dane reference set. See scripts/critic/README.md for the CI harness.
Response contract
All endpoints return JSON with cache-control no-store (per-call results + per-customer billable). Rate-limited per key — watch the X-RateLimit-* headers.
See also
- Integration guide — auth + rate limits.
scripts/critic/README.md— local refine-loop + CI harness.
