Designer Harness

Flow and modes as implemented — tetsuo_core/designer.py + overlays/design.md, post wave-2/3. Philosophy (Case, 07-21): harnesses are lightweight gates — focus, drift-reduction, parallel work. The gate is heavy exactly once: at proof.

1 · How design work arrives

Fable triage declares designThe agent-is-router front door judges the request (or an explicit directive forces the lane). No regex classifies intent anywhere on this path.
Model lane: kimi-for-coding policy: kimi-or-HOLDFigma-bound design work runs on kimi or holds — it never silently falls to another model. Lane precedence: explicit directive > per-issue pref > frontend→kimi > canary > default.
Capability preflight fail-closedPrepare refuses unless ALL are present: brain (tool + index + skill) · /design · /design-loop · /design-qa (skill + checks.py + both law files). A missing capability is a ContractError at the door — never a degraded run.

2 · The kind fork — proof authority is chosen up front

The controller classifies the outcome before the worker exists (classify_kind) and pins it via TETSUO_DESIGN_KIND. The worker cannot change it — evidence that names a different kind fails verify. "Ambiguous design stays on the non-code rail."

design-only

Static deliverable: Figma pages, exported boards, comps, direction gallery. Proof = exported Figma / screenshot pairs. Chosen when static-artifact language dominates or intent is ambiguous.

live-ui

Working interface. Chosen when the ask opens with implement/build/ship/deploy/integrate, or the latest live-action verb outranks design verbs. Proof = the SERVED page, captured by tools/design-qa/capture.mjs.

3 · Declared modes

modemeaningstatus today
railDeterministic pipeline — the /design phase sequence runs the show; the model creates only inside fixed steps.the working default for new design work
agentThe model owns the whole approach; harness supplies only the contract (laws, proofs, gate).declared, exercised via direct asks
hybridRail phases with agent-owned interiors — /design-loop's living-interface cadence.declared; the loop skill is its shape

Declaration also fixes: max_attempts: 2 · supports_resume: true · required gate design-qa · peer harnesses open (the designer may call Strategy or any peer directly and owns local repair until the gate passes).

4 · What the worker is actually told overlays/design.md

5 · The delivery contract — two machine lines

ARTIFACT: <path inside the project>

DESIGN_EVIDENCE: {kind, artifact_sha256, signals, desktop, desktop_sha256, mobile, mobile_sha256, laws, judgments}

Field-exact — extra or missing keys fail. judgments must cover every design-qa row, each {verdict, shot, reason}, each bound to the correct proof (mobile rows to the mobile shot, the rest to desktop).

6 · The gate — where the harness earns its weight

Mechanical verify deterministic, fail-closedRegistry containment (artifact + proofs inside the project) · size caps (result 128k, artifact 10MB, proof 50MB) · SHA-256 bindings artifact/desktop/mobile · kind unchanged from controller · laws named exactly · judgments complete and proof-bound. Any miss = ContractError, run does not deliver.
Independent judgment separate model owns the verdictA verifier model (session_model("verifier")) reads the SAME bound screenshots against the same design-qa rows and issues its own verdict. The worker grades itself for honesty; the judge grades for the gate. This is the split that caught its own P0 on SP-641.
Gate record writtenVerdicts + judge model + usage land in the project's gate record — the run's proof survives the run. Pass → present-first delivery. Fail → local repair (attempt 2 of max 2), then review-needed.

7 · Refinement levers for the working session

Kind classifierclassify_kind is the last regex making a judgment call on this path (live-ui vs design-only). Candidate for the triage declaration to carry kind instead, per the agent-is-router law.
Judgment rows — the design-qa row set defines what "done" means visually. Rows are data; adding one changes both the worker's self-review and the judge's checklist in one place.
Lawsdesign-taste.md / motion-polish-ruleset.md are named-by-path in evidence; swap or version the taste without touching the harness.
Attempts / resumemax_attempts: 2 and warm resume are declaration values, not code.
Judge modelsession_model("verifier") routes through the model table; a new specialist judge is a table edit (model routing stays first-class).
Source of truth: scripts/orchestrate/tetsuo_core/designer.py (586 lines, verify byte-stable since wave 2) · overlays/design.md · page hand-maintained, reviewed like code.