<!-- SOLIDIVISM · part 20 -->
 name: "correctness",
      weight: 1.0,  // Non-negotiable. Must not regress.
      metric: "All existing tests pass; no new errors in console",
      threshold: "100% pass rate (binary: pass/fail)",
    },
    {
      name: "speed",
      weight: 0.8,
      metric: "Frames per second on King's iPhone",
      threshold: ">= 30fps sustained",
      current: "unknown",  // not yet measured on iPhone
    },
    {
      name: "memory",
      weight: 0.7,
      metric: "GPU texture memory",
      threshold: "< 256MB (estimated iPhone Safari limit)",
      current: "~48MB (8 buildings × ~6MB)",
      projected: "~144MB (24 buildings × ~6MB)",
    },
    {
      name: "energy",
      weight: 0.4,
      metric: "Battery drain per hour",
      threshold: "No measurement yet; qualitative: should not cause thermal warning",
      current: "unknown",
    },
    {
      name: "reliability",
      weight: 0.9,
      metric: "Crash-free session rate",
      threshold: "> 99%",
      current: "unknown (no crash reporting)",
    },
    {
      name: "compatibility",
      weight: 0.8,
      metric: "Works on: King's iPhone (primary), desktop browsers (secondary)",
      threshold: "Both must render correctly",
    },
    {
      name: "resource_limits",
      weight: 1.0,  // Non-negotiable. Hard constraints.
      constraints: [
        "localStorage <= 5MB",
        "No new server dependencies",
        "Must work on existing Hetzner infrastructure"
      ]
    }
  ],

  // Trade-off documentation:
  // "If speed and memory conflict, which wins?"
  // Answer depends on weights + thresholds. Correctness and resource_limits are binary gates.
  // Others are weighted. An optimization that improves speed 20% but increases memory 50%
  // is evaluated against: does memory stay under threshold? If yes, net positive (weighted).
  // If no, rejected regardless of speed gain.
}
```

### Evaluation Rule
An optimization candidate is accepted only if:
1. Correctness gate passes (no regressions)
2. Resource limits respected (hard constraints)
3. Weighted improvement across other objectives is net positive
4. Improvement is measured, not assumed (empirical mode, not inference)

---

## 7. CONTROLLED EXPERIMENTAL WORKFLOW

### The Workflow

```
HYPOTHESIZE → DESIGN → BASELINE → EXPERIMENT → MEASURE → ANALYZE → DECIDE
     ↑                                                              │
     └────────────────── ITERATE OR STOP ───────────────────────────┘
```

### Detailed Steps

**1. HYPOTHESIZE (Persona-guided)**
> "It would be nice to know what actually limits this system."
> "Why would knowing that matter?"
> "What evidence would establish the limiting cause?"

```javascript
{
  hypothesis: "Texture memory is the limiting factor for 24-building migration",
  reasoning: "Each building loads ~6MB of canvas textures. 24 × 6MB = 144MB. iPhone Safari GPU limit estimated at 256MB. Headroom exists but is narrowing.",
  mode: "inference",
  confidence: "medium",
  // What would prove/disprove:
  falsifiable: "If 24 buildings render at >30fps on iPhone without memory warnings, hypothesis is wrong (not the limiting factor).",
}
```

**2. DESIGN (Controlled Experiment)**
```javascript
{
  experiment: "Load 24 buildings in staging, measure FPS and memory",
  control: "Current 8-building staging (baseline)",
  variable: "Building count (8 → 24)",
  heldConstant: ["Three.js version", "texture resolution", "browser", "device"],
  metrics: ["fps (mean, min)", "GPU memory estimate", "load time", "console errors"],
  // Pre-registered: what result would support the hypothesis? What would refute it?
  successCriteria: "If fps drops below 30 OR memory warnings appear, hypothesis supported.",
  failureCriteria: "If fps stays above 30 with no warnings, hypothesis refuted — look elsewhere.",
}
```

**3. BASELINE (Measure Before)**
- Run control configuration. Record all metrics. This is the ground truth for comparison.

**4. EXPERIMENT (Measure After)**
- Run experimental configuration. Record all metrics under identical conditions.

**5. MEASURE (Persona-guided)**
> "What changed?"
> "What was measured?"

**6. ANALYZE**
- Statistical comparison (not just "faster" but "faster by Xms ± Y, p < 0.05")
- Check for regressions (correctness gate)
- Evaluate against objective model (weighted)

**7. DECIDE (Persona-guided)**
> "Did the intended improvement occur?"
> "What functionality or resources were affected?"
> "What remains unknown?"

```javascript
{
  decision: "accepted" | "rejected" | "inconclusive" | "needs_refinement",
  reasoning: "...",
  evidence: [...],  // links to measurements
  // If accepted: proceed to modification ledger (Section 8)
  // If rejected: hypothesis preserved, new hypothesis needed
  // If inconclusive: what additional evidence is needed?
}
```

### Regression Tests
Every experiment includes regression tests:
- Existing functionality still works (correctness gate)
- No new console errors
- No visua