Fitness Functions v0.1
Fitness functions turn design judgment into numbers. Every function has an ID, a type, a method, a normalized score from 0 to 1, and a version. Scores are only comparable within the same function version.
Types
| Type | Cost | Runs on |
|---|---|---|
| Gate | Seconds | Every variant. Fail means composite = 0. |
| Measured | Seconds to minutes | Every variant that passes gates. |
| Judged | Model calls | Top 20% after measured scoring. |
| Field | Days, real users | Top 2 or 3 finalists, when the target allows it. |
Gates
| ID | Check | Pass condition | Tool |
|---|---|---|---|
G-A11Y |
Automated accessibility | Zero critical or serious violations | axe-core |
G-CONTRAST |
Text and UI contrast | WCAG 2.2 AA: 4.5:1 body text, 3:1 large text and UI components | axe-core plus computed styles |
G-OVERFLOW |
Horizontal overflow | No horizontal scroll at 320 px width | Playwright: scrollWidth <= clientWidth |
G-RENDER |
Render health | No console errors, no failed requests | Playwright |
G-LOCK |
Locked genes untouched | Locked values identical to genome | Diff against genome.json |
Measured functions
| ID | Measures | Method | Score |
|---|---|---|---|
M-TOKEN |
Token fidelity | Share of computed color, spacing, radius and font values that map to a genome token | Ratio, 0 to 1 |
M-RHYTHM |
Spacing rhythm | Share of vertical gaps on the spacing scale; variance of section spacing | 1 minus normalized deviation |
M-TYPE |
Typographic health | Body size at least 16 px, line length 45 to 75 characters, line height 1.4 to 1.7 for body | Share of text blocks in range |
M-TARGET |
Touch targets | Interactive elements at least 44 by 44 px at 320 and 768 px | Share passing |
M-PERF |
Performance | Lighthouse performance, LCP, CLS, JS weight | Weighted, normalized against budget |
M-RESP |
Responsive stability | Layout keeps reading order and hierarchy across 4 widths | Structural diff score |
M-DIVERSITY |
Novelty vs parents | Perceptual distance from parents and siblings | Used for selection bonus, not composite |
Default performance budget: LCP under 2.0 s on mobile emulation, CLS under 0.05, first-load JS under 120 kB gzip.
Judged functions
Judged functions cover what cannot be measured yet. Each uses a written rubric, a 1 to 5 scale, and 3 independent model judges. The score is the median, normalized to 0 to 1.
| ID | Question the rubric answers |
|---|---|
J-HIERARCHY |
Is it obvious what to look at first, second and third? |
J-CLARITY |
Can a first-time visitor say what this is and what to do within 5 seconds? |
J-BRAND |
Does it read as this brand and no other? |
J-CRAFT |
Alignment, optical balance, detail. Would a senior designer ship it? |
Rules:
- Judges see screenshots plus the target profile, never other variants' scores.
- Judge model names and versions are logged in the run record.
- Calibration: before a run, judges score 10 human-rated reference designs. A judge is used only if its rank correlation with human ratings is at least 0.6.
- Any judged function that repeatedly disagrees with Stage 6 human review is flagged for rubric revision.
Field functions
| ID | Measures |
|---|---|
F-CONVERT |
Primary conversion rate vs baseline |
F-TASK |
Task success rate in moderated or unmoderated tests |
F-TIME |
Time on task |
Field results are reported separately and never mixed into the lab composite.
Composite score
composite = gates_pass * sum(weight_i * score_i) / sum(weight_i)
gates_passis 1 if every gate passes, else 0.- Weights live in
target.jsonand are fixed before Stage 2. Changing weights mid-run starts a new run.
Default weights:
| Function | Weight |
|---|---|
M-TOKEN |
1.0 |
M-RHYTHM |
0.75 |
M-TYPE |
0.75 |
M-TARGET |
0.5 |
M-PERF |
1.0 |
M-RESP |
1.0 |
J-HIERARCHY |
1.5 |
J-CLARITY |
1.5 |
J-BRAND |
1.0 |
J-CRAFT |
1.0 |
Adding a function
- Propose it with ID, method, scoring and the human review reasons that motivated it.
- Validate on at least one past run: does it separate accepted from rejected finalists?
- Ship it in a minor version bump. Old runs keep their old version label.