@ggui-ai/ui-gen 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +2 -2
  2. package/dist/{adapter-Du7P_5Fx.d.ts → adapter-BJwn74rx.d.ts} +49 -1
  3. package/dist/adapters/generation-dispatch.d.ts +32 -7
  4. package/dist/adapters/generation-dispatch.js +1997 -216
  5. package/dist/adapters/generation-dispatch.js.map +1 -1
  6. package/dist/adapters/index.js +29 -6
  7. package/dist/adapters/index.js.map +1 -1
  8. package/dist/advanced/index.d.ts +15 -12
  9. package/dist/advanced/index.js +2013 -270
  10. package/dist/advanced/index.js.map +1 -1
  11. package/dist/{axes-CzLEMDeB.d.ts → axes-CKVCzR_x.d.ts} +1 -1
  12. package/dist/bank-Ctdp3FUA.d.ts +118 -0
  13. package/dist/blueprint-validator.js +416 -92
  14. package/dist/blueprint-validator.js.map +1 -1
  15. package/dist/boilerplate.d.ts +2 -2
  16. package/dist/boilerplate.js +34 -15
  17. package/dist/boilerplate.js.map +1 -1
  18. package/dist/check/index.d.ts +13 -5
  19. package/dist/check/index.js +56 -3
  20. package/dist/check/index.js.map +1 -1
  21. package/dist/classifier/index.d.ts +2 -2
  22. package/dist/compose.d.ts +2 -2
  23. package/dist/{create-ui-generator-GIhzx08x.d.ts → create-ui-generator-N4gRXpcL.d.ts} +11 -4
  24. package/dist/{design-mode-DLufhrNp.d.ts → design-mode-DGWN_Gkm.d.ts} +1 -1
  25. package/dist/{dispatch-BnAH56p4.d.ts → dispatch-BUoXRj_r.d.ts} +6 -4
  26. package/dist/evaluation/axis-checks/index.d.ts +7 -6
  27. package/dist/evaluation/axis-checks/index.js +90 -2
  28. package/dist/evaluation/axis-checks/index.js.map +1 -1
  29. package/dist/evaluation/axis-checks/registry.d.ts +6 -5
  30. package/dist/evaluation/axis-checks/registry.js +88 -1
  31. package/dist/evaluation/axis-checks/registry.js.map +1 -1
  32. package/dist/evaluation/index.d.ts +189 -344
  33. package/dist/evaluation/index.js +1272 -59
  34. package/dist/evaluation/index.js.map +1 -1
  35. package/dist/evaluation/types.d.ts +26 -1
  36. package/dist/evaluation/types.js.map +1 -1
  37. package/dist/fragments/index.d.ts +3 -3
  38. package/dist/{generate-9IeNT4ZY.d.ts → generate-tSO_shQ0.d.ts} +1 -1
  39. package/dist/harness/check/runtime-render/index.d.ts +7 -7
  40. package/dist/harness/check/runtime-render/index.js +416 -92
  41. package/dist/harness/check/runtime-render/index.js.map +1 -1
  42. package/dist/harness/check/runtime-render/render-check-worker.js +393 -88
  43. package/dist/harness/check/runtime-render/render-check-worker.js.map +1 -1
  44. package/dist/harness/index.d.ts +5 -6
  45. package/dist/harness/index.js +69 -20
  46. package/dist/harness/index.js.map +1 -1
  47. package/dist/harness/prompts.d.ts +2 -2
  48. package/dist/harness/prompts.js +10 -1
  49. package/dist/harness/prompts.js.map +1 -1
  50. package/dist/harness/result-types.d.ts +19 -5
  51. package/dist/harness/result-types.js.map +1 -1
  52. package/dist/harness/runtime.d.ts +21 -7
  53. package/dist/harness/runtime.js +36 -17
  54. package/dist/harness/runtime.js.map +1 -1
  55. package/dist/harness/types-public.d.ts +6 -4
  56. package/dist/harness/types-public.js +43 -18
  57. package/dist/harness/types-public.js.map +1 -1
  58. package/dist/harness/validator-trace-sink.d.ts +6 -5
  59. package/dist/hash.d.ts +1 -1
  60. package/dist/index.d.ts +64 -13
  61. package/dist/index.js +2023 -270
  62. package/dist/index.js.map +1 -1
  63. package/dist/patch.d.ts +5 -5
  64. package/dist/policy.d.ts +1 -1
  65. package/dist/{prompts-YU9piOgs.d.ts → prompts-BhNUuRoZ.d.ts} +1 -1
  66. package/dist/tools/get-primitives-ts.d.ts +1 -1
  67. package/dist/tools/get-primitives-ts.js +1 -1
  68. package/dist/tools/get-primitives-ts.js.map +1 -1
  69. package/dist/tools/render-check-worker.js +8 -1
  70. package/dist/tools/render-check-worker.js.map +1 -1
  71. package/dist/{types-BOvHNG7K.d.ts → types-Dh1s4K9j.d.ts} +1 -1
  72. package/dist/types-public-B7wn4ce5.d.ts +959 -0
  73. package/dist/validation/index.d.ts +1 -1
  74. package/dist/validation/index.js +1 -1
  75. package/dist/validation/index.js.map +1 -1
  76. package/dist/visual-evaluator-C9L-o6ap.d.ts +639 -0
  77. package/dist/workflows.d.ts +5 -5
  78. package/package.json +12 -12
  79. package/src/adapters/generation-dispatch.ts +38 -2
  80. package/src/adapters/tools.ts +2 -1
  81. package/src/boilerplate/free-design-prompt.ts +4 -4
  82. package/src/boilerplate/generate.ts +26 -1
  83. package/src/boilerplate/hard-sections.ts +14 -14
  84. package/src/boilerplate/system-prompt.ts +1 -1
  85. package/src/boilerplate/templates/layouts/chat-mobile.tsx.tmpl +3 -1
  86. package/src/boilerplate/templates/layouts/chat-universal.tsx.tmpl +3 -1
  87. package/src/boilerplate/templates/layouts/fullscreen-desktop.tsx.tmpl +3 -1
  88. package/src/boilerplate/templates/layouts/fullscreen-universal.tsx.tmpl +3 -1
  89. package/src/check/index.ts +1 -0
  90. package/src/check/run-tier0.ts +6 -3
  91. package/src/check/sample-props.ts +63 -0
  92. package/src/coding-agent/tools.ts +4 -1
  93. package/src/contract-context.ts +1 -1
  94. package/src/create-harness.ts +3 -3
  95. package/src/create-ui-generator.ts +20 -1
  96. package/src/evaluation/__fixtures__/png.ts +100 -0
  97. package/src/evaluation/axis-checks/checks/state-merge.ts +1 -1
  98. package/src/evaluation/axis-checks/checks/universal.ts +111 -0
  99. package/src/evaluation/axis-checks/dispatch.ts +4 -1
  100. package/src/evaluation/cost-tracker.ts +54 -6
  101. package/src/evaluation/criteria/bank.ts +85 -0
  102. package/src/evaluation/criteria/context.ts +52 -0
  103. package/src/evaluation/criteria/edge-probe.ts +286 -0
  104. package/src/evaluation/criteria/edge.ts +202 -0
  105. package/src/evaluation/criteria/resolve.ts +207 -0
  106. package/src/evaluation/criteria/select.ts +79 -0
  107. package/src/evaluation/index.ts +27 -0
  108. package/src/evaluation/ink-extent.ts +200 -0
  109. package/src/evaluation/judge-spend.ts +48 -0
  110. package/src/evaluation/theme-css.ts +12 -5
  111. package/src/evaluation/types-public.ts +221 -3
  112. package/src/evaluation/types.ts +19 -0
  113. package/src/evaluation/visual-evaluator.ts +853 -51
  114. package/src/harness/check/runtime-render/adapter.ts +18 -0
  115. package/src/harness/check/runtime-render/probe-pending.ts +111 -0
  116. package/src/harness/check/runtime-render/render-check-host.ts +10 -6
  117. package/src/harness/check/runtime-render/render-check-worker.ts +6 -3
  118. package/src/harness/check/runtime-render/render-check.ts +417 -133
  119. package/src/harness/check/runtime-render/walk.ts +200 -0
  120. package/src/harness/coding/assemble-result.ts +2 -0
  121. package/src/harness/coding/generate-task-runner.ts +30 -0
  122. package/src/harness/coding/init-session.ts +5 -3
  123. package/src/harness/coding/run-coding-turn.ts +12 -4
  124. package/src/harness/coding/run-eval-round.ts +82 -3
  125. package/src/harness/in-loop-evaluation.ts +39 -0
  126. package/src/harness/llm-router.ts +58 -1
  127. package/src/harness/result-types.ts +9 -0
  128. package/src/harness/runtime.ts +14 -0
  129. package/src/harness/types-public.ts +10 -1
  130. package/src/harness-tool-names.ts +38 -0
  131. package/src/index.ts +17 -0
  132. package/src/internal/verdict-line.ts +33 -0
  133. package/src/run-check.ts +2 -0
  134. package/src/taught-tokens.ts +32 -0
  135. package/src/tools/get-primitives-ts.ts +1 -1
  136. package/src/tools/get-wire.ts +1 -1
  137. package/src/tools/render-check-worker.ts +2 -1
  138. package/src/tools/render-check.ts +8 -67
  139. package/src/tools.ts +11 -1
  140. package/src/validation/primitives.ts +1 -1
  141. package/dist/llm-router-DwwUK1bz.d.ts +0 -265
  142. package/dist/types-public-Bk6d1WLN.d.ts +0 -451
@@ -20,6 +20,7 @@
20
20
 
21
21
  export type Priority = "P0" | "P1" | "P2";
22
22
 
23
+ import type { VisionFinishReason } from '../harness/llm-router.js';
23
24
  import type { GenerationRuntimeProbeOutcome, GenerationRuntimeProbeStatus } from "@ggui-ai/mcp-server-core";
24
25
  import type { CanvasClass, DesignMode } from "../design-mode.js";
25
26
 
@@ -61,6 +62,11 @@ export interface EvalIssue {
61
62
  description: string;
62
63
  fix: string;
63
64
  line?: number;
65
+ /**
66
+ * The visual leg's provenance (ggui#1545): `judge` (the model's finding) or `instrument` (a deterministic
67
+ * measurement). Absent on every other leg's issues. `visualEvaluation.actOn` acts on `judge` only.
68
+ */
69
+ origin?: "judge" | "instrument";
64
70
  }
65
71
 
66
72
  /**
@@ -100,6 +106,23 @@ export interface ProbeHostLoad {
100
106
  readonly cores: number;
101
107
  }
102
108
 
109
+ /**
110
+ * ggui#1398 — whether the controls the probe clicked showed they were
111
+ * working once their action was pending. Report-only: it is read by the
112
+ * benchmark and never counted into the probe's warnings or fed back to
113
+ * the coding loop.
114
+ */
115
+ export interface ProbePendingAffordance {
116
+ /** Controls the pending phase marked pending: those whose click dispatched their action (click or submit wiring) and that were still in the page. `visible + missing.length === dispatched`. */
117
+ readonly dispatched: number;
118
+ /** Of those, how many visibly changed while pending (disabled, busy, text, or replaced). */
119
+ readonly visible: number;
120
+ /** The actions whose control did not visibly change, including one whose card threw while pending. */
121
+ readonly missing: readonly string[];
122
+ /** Actions whose control was no longer in the page when its turn came (the card replaced it, or blanked after a throw): never marked, not counted as dispatched. */
123
+ readonly gone: readonly string[];
124
+ }
125
+
103
126
  /**
104
127
  * The engine's own fields on a probe's meta, beside the outcome a
105
128
  * generation's metadata reports: why a probe did not finish, its render
@@ -116,6 +139,11 @@ export interface RuntimeProbeMetaDetail {
116
139
  readonly hostLoad?: ProbeHostLoad;
117
140
  /** Time the check waited for a probe slot before it started, ms; present only when > 0 (ggui#1380 C2b). */
118
141
  readonly queuedMs?: number;
142
+ /**
143
+ * `ran` only: the pending-affordance walk (ggui#1398). Absent when no
144
+ * action walk ran, so "no data" and "0 of 0" read differently.
145
+ */
146
+ readonly pendingAffordance?: ProbePendingAffordance;
119
147
  }
120
148
 
121
149
  /**
@@ -143,9 +171,12 @@ export interface RuntimeProbeMetaDetail {
143
171
  * The verdict and the repair trigger are two different questions. The
144
172
  * verdict is `fail` on any failing check. The one repair turn a probe-only
145
173
  * round buys fires on a `render-no-throw` fail the engine recognises
146
- * (`isRecoverableRenderCrash`) and on nothing else: a `fail` verdict whose
147
- * checks are `prop-sensitivity`, `action-wiring` or any other kind is
148
- * recorded here and never fed back.
174
+ * (`isRecoverableRenderCrash`) and on nothing else: on the PROBE-ONLY round a
175
+ * `fail` verdict whose checks are `prop-sensitivity`, `action-wiring` or any
176
+ * other kind is recorded here and never fed back. The same meta is stamped on
177
+ * the EVALUATION lane, where a `prop-sensitivity` fail buys that lane's own
178
+ * contract-feedback round (ggui#1261, `FEEDBACK_PROBE_CHECKS`) — a different
179
+ * turn under a different rule, not the repair turn.
149
180
  */
150
181
  export type RuntimeProbeMeta = GenerationRuntimeProbeOutcome & RuntimeProbeMetaDetail;
151
182
 
@@ -331,8 +362,173 @@ export interface CanvasJudgeRecord {
331
362
  readonly sigma: number;
332
363
  /** The judge's per-canvas critique per sample — the words beside a swing. */
333
364
  readonly notes: string[];
365
+ /**
366
+ * ggui#1127 — the cause of each scoring sample whose answer failed to parse and was SALVAGED: its four dimensions
367
+ * were recovered from the closed prefix, its issues kept only as far as they closed, its critique lost. One entry
368
+ * per salvaged sample; absent when every sample parsed. The salvaged sample's score still counts.
369
+ */
370
+ readonly salvaged?: readonly JudgeSalvageCause[];
371
+ /**
372
+ * ggui#1127 — the criteria call's answer was salvaged. A salvage keeps no criteria, so that frame's judge rows read
373
+ * "not answered" with this cause rather than a clean `n/a`. Absent when the call parsed or was not asked.
374
+ */
375
+ readonly criteriaSalvaged?: JudgeSalvageCause;
376
+ /**
377
+ * ggui#1687 — the model asked for, and every model the provider said answered this canvas's calls (scoring and
378
+ * criteria), deduplicated. `served` is empty when no provider named one: unknown, never "the requested model".
379
+ */
380
+ readonly models?: { readonly requested: string; readonly served: readonly string[] };
381
+ }
382
+
383
+ /**
384
+ * ggui#1687 — what the criteria call's answer held, before resolution. A row the judge left unanswered reads `n/a`
385
+ * either way; this says whether the call came back empty, cut, or with entries the parser had to drop.
386
+ */
387
+ export interface CriteriaAnswerCounts {
388
+ /** The answer carried a `criteria` array. `false`: absent or not an array, so no row was read from it. */
389
+ readonly array: boolean;
390
+ /** Entries in the array. */
391
+ readonly received: number;
392
+ /** Entries kept: an object with a string id and a verdict of pass, fail or n/a. */
393
+ readonly kept: number;
394
+ /** Entries dropped, by why. */
395
+ readonly dropped: { readonly notObject: number; readonly badId: number; readonly badVerdict: number };
396
+ }
397
+
398
+ /**
399
+ * ggui#1127 — why a judge answer that failed to parse had to be salvaged. `output-cap`: the provider reported it
400
+ * stopped at the output cap. `malformed`: the provider reported a normal stop, so the answer ended but did not
401
+ * parse. `stopped`: the provider stopped it for another reason it named (a safety stop, or one it reports as
402
+ * other), so it is cut, not malformed. `unknown`: the provider or route reported no stop reason. Never inferred
403
+ * from the answer's length.
404
+ */
405
+ export type JudgeSalvageCause = "output-cap" | "malformed" | "stopped" | "unknown";
406
+
407
+ /** ggui#1127 — salvaged judge answers across a canvas run, per leg, as N of M. */
408
+ export interface JudgeSalvageCounts {
409
+ /** Scoring answers: `answers` = samples that parsed or were salvaged, `salvaged` = those salvaged. */
410
+ readonly scoring: { readonly salvaged: number; readonly answers: number };
411
+ /** Criteria calls: `answered` = calls that parsed or were salvaged, `salvaged` = those salvaged (criteria lost). */
412
+ readonly criteria: { readonly salvaged: number; readonly answered: number };
413
+ }
414
+
415
+ // ─── Visual criteria (ggui#1436) ──────────────────────────────────────────
416
+ // The judge's typed criteria block per canvas — report-only beside the score
417
+ // until a later word flips a gate to it. Every field below is optional on the
418
+ // stamps so yesterday's `eval.json` and an old judge answer still parse (N−1).
419
+ import type { FetchShape, LayoutShape, RenderShape, RiskTier, StateShape, WriteShape } from "../classifier/axes.js";
420
+
421
+ export type CriteriaSeverity = "must" | "should";
422
+ export type CriteriaVerdict = "pass" | "fail" | "n/a";
423
+ /** The method that produces a verdict: an instrument's measurement, the vision judge off the frame, or a person's eye. */
424
+ export type CriteriaMethod = "instrument" | "judge" | "human";
425
+ /** The method's readiness, as the bank's author wrote it — the only source of an `n/a` that is not the judge's own. */
426
+ export type CriteriaStatus = "live" | "reference" | "planned" | "manual";
427
+ /**
428
+ * How a criterion entered the selection: bank-level (`static`, an empty scope) or by the selector's
429
+ * rules for this card (`context`). A model PROPOSING a criterion at judge time is RESERVED and not a
430
+ * member until a consumer exists — it would be `should`-only, recorded verbatim, never a gate.
431
+ */
432
+ export type CriteriaSource = "static" | "context";
433
+ export type CriteriaChroma = "achromatic" | "chromatic" | "unknown";
434
+ /** The classifier's shape axes, as hashed into the set id. */
435
+ export interface CriteriaAxes {
436
+ render: RenderShape;
437
+ state: StateShape;
438
+ writes: WriteShape;
439
+ fetch: FetchShape;
440
+ layout: LayoutShape;
441
+ }
442
+ /** The selector's inputs, stored with the verdict so a reader recomputes `criteriaSetId` from the record alone. */
443
+ export interface CriteriaContext {
444
+ canvas: CanvasClass;
445
+ hasActions: boolean;
446
+ riskTier: RiskTier;
447
+ axes: CriteriaAxes;
448
+ chroma: CriteriaChroma;
449
+ profilePresent: boolean;
450
+ /** The harness's shell as named; `unknown` when the round carries none. */
451
+ shell: string;
452
+ /** The caller's item kind (a bootstrap mint's `hello`); hashed when present. */
453
+ kind?: string;
454
+ /** The styling preset in force (the profile's aesthetic id); a recipe is selected only under its preset. */
455
+ preset?: string;
456
+ }
457
+ /** What was asked and why — recorded BEFORE the judge runs. Omission is the selector's decision. */
458
+ export interface CriteriaSelection {
459
+ id: string;
460
+ source: CriteriaSource;
461
+ reason: string;
462
+ }
463
+ /** One criterion's verdict; `n/a` is the judge's answer ("cannot read this off the frame"), an unanswered id, a tie, or a method whose `status` is not live. */
464
+ export interface CriterionVerdict {
465
+ id: string;
466
+ severity: CriteriaSeverity;
467
+ method: CriteriaMethod;
468
+ status: CriteriaStatus;
469
+ source: CriteriaSource;
470
+ verdict: CriteriaVerdict;
471
+ evidence: string;
472
+ /**
473
+ * ggui#1663 — a measured reading beside a judge row, REPORT-ONLY: the row's `verdict` stays the judge's, so this
474
+ * changes no verdict, score or bar. Present only on rows an instrument answers beside the judge (`space.edge`).
475
+ */
476
+ instrument?: { verdict: CriteriaVerdict; evidence: string };
477
+ }
478
+ /** ggui#1687 — the criteria call as it came back: its answer's counts, ids it answered outside the bank, its stop. */
479
+ export interface CriteriaCallRecord {
480
+ readonly answer: CriteriaAnswerCounts;
481
+ /** Kept entries whose id names no row of the bank. */
482
+ readonly unknownIds: number;
483
+ /** The provider's normalized stop reason (`length` = the output cap); absent when it reported none. */
484
+ readonly finishReason?: VisionFinishReason;
485
+ }
486
+ export interface CriteriaBlock {
487
+ /** sha256(bank version | selector version | canonical context), 16 hex — the block's own digest. */
488
+ criteriaSetId: string;
489
+ bankVersion: string;
490
+ selectorVersion: string;
491
+ context: CriteriaContext;
492
+ selection: CriteriaSelection[];
493
+ verdicts: CriterionVerdict[];
494
+ /** ggui#1687 — the call that answered this block, when one did. Absent for a block resolved with no call. */
495
+ call?: CriteriaCallRecord;
496
+ }
497
+ /** The roll-up across canvases; a `must` at `n/a` is listed, never counted as a pass. */
498
+ export interface CriteriaRollup {
499
+ mustFailed: string[];
500
+ shouldFailed: string[];
501
+ mustNa: string[];
334
502
  }
335
503
 
504
+ /** ggui#1492 — a host"s frame round the inline card, as data. Colours are `#rrggbb`; the ring"s `alpha` is 0..1. */
505
+ export interface HostInlineFrame {
506
+ /** The frame"s surface — what shows behind a transparent card, and under the floor"s residual. */
507
+ readonly surface: string;
508
+ /** The room the frame sits in (the page ground round it). */
509
+ readonly ground: string;
510
+ readonly ring: { readonly widthPx: number; readonly color: string; readonly alpha: number };
511
+ readonly radiusPx: number;
512
+ /** The host"s minimum frame height: a card shorter than it sits in a frame this tall, and the visitor sees the rest as void. */
513
+ readonly minHeightPx?: number;
514
+ }
515
+ /** ggui#1492 — how a host presents one canvas: the label the judge is told, the page ground, and (the inline card only) its frame. */
516
+ export interface CanvasHostPresentation {
517
+ readonly label: string;
518
+ /** The page ground under a fill canvas"s panel; the inline card"s ground lives on its {@link HostInlineFrame}. */
519
+ readonly ground?: string;
520
+ readonly frame?: HostInlineFrame;
521
+ }
522
+ /** ggui#1492 — why the judge did not draw a canvas's host presentation. The codes are the lane reader's own. */
523
+ export type HostPresentationIgnoredReason = "label_missing" | "color_not_hex" | "frame_off_inline" | "frame_malformed" | "ground_on_inline";
524
+ /**
525
+ * ggui#1492 — what the judge DID with a canvas's host presentation, read from the judge itself: `applied` carries
526
+ * the presentation it drew, `ignored` the reason it drew none. Absent when the caller supplied no presentation.
527
+ */
528
+ export type CanvasPresentationOutcome =
529
+ | { readonly status: "applied"; readonly applied: CanvasHostPresentation }
530
+ | { readonly status: "ignored"; readonly reason: HostPresentationIgnoredReason };
531
+
336
532
  export interface CanvasVisualSummary {
337
533
  canvas: CanvasClass;
338
534
  viewport: { width: number; height: number };
@@ -344,8 +540,19 @@ export interface CanvasVisualSummary {
344
540
  contentHeight: number | null;
345
541
  /** `contentHeight > viewport.height` — measured on every canvas, judged per `canvasFitPolicy`. */
346
542
  overflow: boolean;
543
+ /**
544
+ * ggui#1120 — how far down the capture anything was painted: the last inked row over the measured
545
+ * region's height (inside a drawn host panel's chrome on md/lg/xl), read from the screenshot's
546
+ * pixels against their dominant colour. `0` is the blank the judge fails (`canvas-blank`); every
547
+ * other value is reported, never scored. `null` when the capture could not be read.
548
+ */
549
+ inkRatio: number | null;
347
550
  /** How `score` was reached — always present (ggui#1072). */
348
551
  judge: CanvasJudgeRecord;
552
+ /** ggui#1436 — the typed criteria block, when a bank was configured; report-only. */
553
+ criteria?: CriteriaBlock;
554
+ /** ggui#1492 — what the judge did with this canvas's host presentation, when one was supplied. */
555
+ presentation?: CanvasPresentationOutcome;
349
556
  /**
350
557
  * How the judge composed the mount (ggui#1100): `'fill'` on every
351
558
  * fullscreen canvas — the served runtime's fit, the root stretched to
@@ -382,6 +589,8 @@ export interface VisualEvalSummary {
382
589
  design?: { readonly src: string; readonly srcSha256: string };
383
590
  /** The mode the judge's tokens were composed in, when the caller said (ggui#1076). */
384
591
  themeMode?: 'light' | 'dark';
592
+ /** ggui#1436 — the criteria roll-up across canvases, when any canvas carries a block; report-only. */
593
+ criteria?: CriteriaRollup;
385
594
  }
386
595
 
387
596
  // ─── Quality mode ──────────────────────────────────────────────────────────
@@ -407,6 +616,7 @@ export const DEFAULT_QUALITY_CONFIG: QualityConfig = {
407
616
  // `./axis-checks/`.
408
617
 
409
618
  import type { DataContract } from "@ggui-ai/protocol";
619
+ import type { JsonObject } from "@ggui-ai/protocol";
410
620
  import type { AxisVector, Classification } from "../classifier/axes.js";
411
621
  import type { AxisKey } from "../fragments/index.js";
412
622
 
@@ -433,6 +643,14 @@ export interface AxisCheckInput {
433
643
  * default (a silent `lg` would be the same guess with a nicer face).
434
644
  */
435
645
  canvas?: CanvasClass;
646
+ /**
647
+ * The props the probe and the judge RENDERED the source with (ggui#1285) — a bootstrap order's
648
+ * `sampleProps`, the bench commit's fixture. They are judging data, not the request: a literal in
649
+ * the source that equals one of these values, and that the request never stated, is baked copy a
650
+ * visitor sees whenever the agent leaves the prop out. Populated on the served loop and at
651
+ * auto-commit; ABSENT where the caller has none — the check stands down, it never guesses.
652
+ */
653
+ fixtureProps?: JsonObject;
436
654
  }
437
655
 
438
656
  /**
@@ -1,3 +1,4 @@
1
+ import type { CriteriaAnswerCounts } from './types-public.js';
1
2
  // packages/ui-gen/src/evaluation/types.ts
2
3
 
3
4
  /**
@@ -28,11 +29,25 @@ export interface EvaluationIssue {
28
29
  severity: 'critical' | 'major' | 'minor';
29
30
  /** Suggested fix for the agent to apply */
30
31
  fix: string;
32
+ /**
33
+ * Who produced it, on the visual leg (ggui#1545): `judge` for the model's own findings, `instrument` for a
34
+ * deterministic measurement (fit, overflow, blank). Absent on issues from other evaluators. The loop's
35
+ * `visualEvaluation.actOn` acts on `judge` findings only, so a new instrument check never joins the treatment
36
+ * by accident: it has to say it is a judge finding, and absence reads as "not acted on".
37
+ */
38
+ origin?: 'judge' | 'instrument';
31
39
  }
32
40
 
33
41
  /**
34
42
  * Result of a single evaluation round.
35
43
  */
44
+ /** One judge answer to a criterion (ggui#1436), as parsed — before the K-majority. */
45
+ export interface CriteriaAnswer {
46
+ id: string;
47
+ verdict: 'pass' | 'fail' | 'n/a';
48
+ evidence: string;
49
+ }
50
+
36
51
  export interface EvaluationResult {
37
52
  /** Whether the component passed the quality threshold */
38
53
  passed: boolean;
@@ -48,6 +63,10 @@ export interface EvaluationResult {
48
63
  inputTokens?: number;
49
64
  /** Output tokens consumed by the evaluation LLM call */
50
65
  outputTokens?: number;
66
+ /** ggui#1436 — the judge's criteria answers, when the prompt asked for them; never part of the score. */
67
+ criteriaAnswers?: CriteriaAnswer[];
68
+ /** ggui#1687 — what the answer's criteria array held and what the parser dropped; set whenever the answer parsed. */
69
+ criteriaCounts?: CriteriaAnswerCounts;
51
70
  }
52
71
 
53
72
  /**