ADRs
ADR 0010 — Completeness: матрица combinations, не point check
  • Date: 2026-05-22
  • Status: Accepted
  • Feature: URL-import
  • Affects: url_import_spec.md § IV Phase 8

Context

После acceptance gate (ADR 0009) проверяет ОДНУ конфигурацию (default state, 1440 viewport, light theme). Это routing decision: "code path сработал или нужен vision?"

Но это не отвечает на другой вопрос: "Мы полностью забрали компонент со всеми его проявлениями?"

Юзер явно отделил концепции:

"ОК, это критерии оценки код справился или подключать вижн. А теперь я хочу обсудить то что нужно забирать из компонента. Критерии того что мы полностью все забрали из ссылки. Вот компонент — мы забрали цвет, токены, состояния — что ещё нужно для того чтобы сказать 'Мы полностью забрали твой компонент, теперь он у нас такой как у тебя на сайте'."

Это отдельная концепция — completeness verification.

ИзмерениеЧто измеряетКогда
Acceptance gate (ADR 0009)"Code path сработал?"После каждой generation, для routing
Completeness (this ADR)"Захватили весь компонент во всех проявлениях?"После финальной TSX, для declaring done

Evolution

V1 (rejected): weighted multi-dimensional checklist

  • color_score × 0.3 + spacing × 0.2 + states × 0.25 + tokens × 0.15 + ...
  • Юзер: "не жизнеспособные, документ ради документа"

V2 (rejected): список обязательных полей (color ✓ tokens ✓ states ✓ aria ✓)

  • Не отвечает на "полностью" — компонент может иметь все поля но визуально отличаться в edge case

V3 (final): матрица комбинаций

Decision

Completeness = matrix verification across state × viewport × theme:

async function completenessCheck(component, captureMatrix): Promise<CompletenessReport> {
  const combinations = generateCombinations({
    themes: Object.keys(captureMatrix),  // ['light'] or ['light', 'dark']
    viewports: [320, 768, 1024, 1440],
    states: detectAllStates(component)   // ['default', 'hover', 'focus', 'active', 'disabled', ...]
  });
 
  const results = await Promise.all(combinations.map(async combo => {
    const original = captureMatrix[combo.theme][combo.viewport][combo.state];
    const generated = await renderGenerated(component.tsx, combo);
    const diff = await pixelmatch(original, generated, {
      ignoreText: true,    // юзер свой контент вставит
      ignoreImages: true
    });
    return { combo, diff, pass: diff < 0.15 };
  }));
 
  return {
    complete: results.filter(r => r.pass).length / results.length >= 0.90,
    failedCombos: results.filter(r => !r.pass).map(r => r.combo)
  };
}

Threshold: 90% combinations pass pixel-diff < 0.15.

Why matrix wins

  1. Эмпирическая, не калибруемая (как и acceptance gate)
  2. Покрывает проявления компонента, не статические поля — кнопка имеет default/hover/focus/active/disabled × 4 viewports × 2 themes = 40 combinations
  3. Допускает граничные failures — один редкий state (например custom "loading" в exotic case) не блокирует declaring компонент done
  4. Failed combinations явно видны в report → юзер знает что именно сломалось ("hover at 320px viewport in dark theme")
  5. ignoreText + ignoreImages — сверяем структуру/spacing/colors, не content (юзер свой текст вставит)

Threshold rationale

pixel-diff < 0.15:

  • Строже чем acceptance gate < 0.30 — здесь сверяем тот же компонент в разных combos, не оригинал vs generated
  • Расхождения должны быть малы (только из-за ignoreText/Images)

90% combinations pass:

  • 100% слишком строго — один редкий state может законно ломаться (e.g. browser quirk)
  • 80% слишком loose — компонент с 3+ broken states назвать complete нельзя

Consequences

Pros:

  • Чёткий definition of "done" — measurable, не subjective
  • Граничные fails не топят компонент
  • Failed combos surface specific issues для manual review

Cons:

  • Compute cost — render 40 combinations per компонент, ~10s overhead
  • При low capture matrix (single theme detected, no dark) — fewer combinations, меньше confidence

Capture matrix dependencies

Matrix completeness требует Phase 2 (themes + states + viewports) capture full coverage. Если Phase 2 partial (e.g. failed to detect theme mechanism) → matrix smaller → lower confidence. Это reflected в failed_combinations в manifest.

Alternatives rejected

A. Weighted checklist

  • ❌ Same issues как acceptance gate V1 (см ADR 0009)

B. "All required fields filled" check

  • ❌ Не отвечает на "полностью" — fields могут быть, edge cases visually ломаются

C. Manual review of every component

  • ❌ Не scales — small-biz юзер impотит 10+ компонентов

D. Strict 100% pass

  • ❌ False blocks for compliant components с rare edge cases

Cross-references