Контракт интегратора
00 / module apiCONSUMES
PROVIDES
DOES NOT OWN
1.11 оркестрирует владельцев, но не переопределяет их метрики.
Главная архитектурная поправка
01 / no circular dependencyPASS A — intrinsic
До появления окружения точка получает только свойства, не требующие контекста.
PASS B — contextual
После placement, соседей, grid, conflicts и local background вес пересчитывается владельцем 1.01.
visualWeightBase, затем выполнить contextual recompute.Полный последовательный pipeline
02 / deterministic execution orderContextual weight loop
03 / explicit feedback cycleFreshness contract
Это не даёт модулю использовать старый contrast после перемещения точки или старый crowding после изменения соседей.
Dirty graph и точечный recompute
04 / dependency invalidation| Что изменилось | Нужно инвалидировать | Почему |
|---|---|---|
point.positionN | 1.03, 1.04, 1.05*, 1.06, 1.07, 1.08*, 1.09, 1.10, 1.01B | меняются расстояния, окружение, конфликт, фон и contextual weight |
point.radiusShortN | 1.03, 1.04, 1.06, 1.07*, 1.08*, 1.09, 1.10*, 1.01B | меняются surface gap, occupancy, contact clearance и sample footprint |
point.color | 1.10, 1.01B | меняется local contrast → contextual weight |
visualWeightContextual | 1.04, 1.06, 1.07, 1.08 | эти модули могут использовать effective fresh weight |
grid | 1.02*, 1.05*, 1.06, 1.07* | grid может быть candidate provider или structural constraint |
protectedZones | 1.02, 1.08, 1.09 | меняется feasible geometry |
stylePreset | все модули, использующие STYLE_PRESET | политика кандидатов и диапазоны могли измениться |
* — только если конкретный объект/кандидат использует соответствующую зависимость. Dirty propagation должна быть по dependency flags, а не слепо запускать всё.
Генерация кандидатов
05 / bounded searchDeterministic base
Сначала генерируются структурные кандидаты из ролей, grid, anchors и разрешённых областей.
Seeded variants
Затем разрешён bounded jitter, изменение размера и локальных вариантов.
Hard filter first
Невалидные кандидаты не получают эстетического score.
candidateBudget = clamp(12 + 3*N_semantic, 24, 128); для noise-field используется отдельный генератор 1.08.Corrective pass
06 / repair instead of guessДопустимые операции
Любая операция обязана перечислить, какие модули становятся DIRTY.
Источник correction request
1.11 не изобретает причину коррекции. Он исполняет запрос владельца правила и ведёт audit log.
Random — только последний слой
07 / reproducible variationОдинаковый вход + seed + module versions → одинаковые candidates.
Random не выходит за диапазоны owner-модулей.
Hard, semantic и global rules всегда выше random.
Каждое stochastic решение сохраняет seed fragment и выбранное значение.
Worked example: почему нужен второй проход
08 / visual proofDeterministic tests
09 / orchestration tests| Test | Input event | Expected orchestration result |
|---|---|---|
| T01 | fresh input, no context | run 1.01 PASS A; never request PASS B before placement/context exists |
| T02 | point position changed | invalidate relation/context modules; 1.10 background sample becomes stale; then 1.01B stale |
| T03 | color changed only | rerun 1.10 → 1.01B; do not rerun geometry unless contextual weight change invalidates weight-dependent modules |
| T04 | Compo 1.12 missing | return valid candidates with status LOCALLY_VALID_UNRANKED; no invented best candidate |
| T05 | hard conflict from 1.09 | reject or mandatory repair before score aggregation |
| T06 | same input + same seed + same versions | candidate ids, stochastic deltas and audit trail deterministic |
| T07 | stale localContrast after move | 1.01B must omit it; must not reuse previous value |
| T08 | maxIterations reached with dirty set | status NON_CONVERGED + diagnostics; never silently call result final |