COMPO · 2.23 · LINE CONTEXT ADAPTER

Линия
в глобальном
контексте.

Финальный интеграционный модуль темы 2. Он не превращает линию в владельца глобальной композиции: 2.23 принимает внешние context/global directives, проверяет их область действия, создаёт immutable projection поверх line target, маршрутизирует correction requests к владельцам 2.02–2.18 и фиксирует, почему глобальный слой может предпочесть не локального победителя 2.20.

ModuleCompo 2.23
Scopeline ↔ context/global integration protocol
Ownscontext projection + override application trace
Consumes2.20 results + 2.22 descriptors + external directives
Provideseffective line target + correction routing + audit
FinalityADAPTER ONLY · NOT GLOBAL SOLVER

Контракт интеграционного слоя

00 / module api

2.23 связывает локальную line subsystem с внешним context/global pass. Он не является новым scorer и не решает композицию целиком. Его результат — проверяемая проекция внешнего решения в разрешённые line-side inputs.

SCOPE

Context-aware target projection, external selection trace и owner-routed correction для line candidates.

BOUNDARY

Никакого пересчёта global metrics, никакого прямого изменения line geometry, никакого generic rule-override budget.

DEFERRED

Global pipeline → 48.xx; global scoring → 49.xx; universal override schema/budgets/conflicts → 65.xx.

CONSUMES / PROVIDES

Consumes
LineStructureCandidate[]                  // 2.19
LineSystemScoreResult[]                // 2.20 local ranking
MaskCropSeamResult[]?              // 2.22 descriptors
LineSystemTarget                       // base target used by 2.20
ContextDirectiveRef[]                  // EXTERNAL owner
ExternalSelectionDirective?            // EXTERNAL global authority
ExternalContextMetricRef[]             // references only
LineContextPolicy
Compo0.seed / lineage
Provides
LineContextProjection {
  status,
  baseTargetRef,
  effectiveTarget,
  targetPatchTrace[],
  localRankingRef,
  externalSelectionRef?,
  selectedCandidateRef?,
  localVsContextDelta,
  correctionRequests[],
  ignoredDirectives[],
  unresolvedConflicts[],
  deferredGlobalRefs[],
  recomputePlan,
  audit
}
CANONICAL HANDOFF TYPES. 2.19 → LineStructureCandidate[]; 2.20 → LineSystemScoreResult[]; 2.22 → MaskCropSeamResult[]. 2.23 не вводит aliases для этих сущностей.
CONTINUATION, NOT GLOBAL REDESIGN. 2.23 завершает line subsystem интеграционным протоколом. Он не реализует заранее темы 48, 49 или 65 и не создаёт временный «мини-глобальный движок» внутри темы линии.

Ownership: адаптер, а не глобальный owner

01 / ownership boundary

Самая важная граница 2.23 — отличить «линия реагирует на глобальный контекст» от «линия владеет глобальным контекстом».

OWNS

Line-side projection

lineContext.effectiveTarget
lineContext.patchTrace
lineContext.overrideApplicationTrace
lineContext.recomputePlan

CONSUMES / REFERENCES

External authority

global/context diagnostics, hierarchy/balance/negative-space/eye-flow owners, external selection decision, future RuleOverride references. Только по ID + provenance + authority.

DOES NOT OWN

Global composition

global.balance, global.hierarchy, global.eyeFlow, global.negativeSpace, global rank/score, override budget, exception cost.

Reserved future owners

Future areaReserved ownerЧто 2.23 делает сейчас
Multi-pass local → context → global orchestrationCompo 48.xxТолько отдаёт typed recompute plan; не управляет всей сценой и convergence.
Global MetricResult aggregation / rankingCompo 49.xxХранит external refs; не вычисляет globalScore и не смешивает его с localScore 2.20.
Generic RuleOverride / budget / conflictsCompo 65.xxПринимает уже авторизованный directive ref. Общий override budget здесь не изобретается.
LOCAL RESULT = owned by 2.20 CONTEXT PROJECTION = owned by 2.23 GLOBAL METRIC = owned by future global module GLOBAL SELECTION = external authority / future global solver GENERIC OVERRIDE = future 65.xx 2.23 MAY EXPLAIN THE BRIDGE. 2.23 MUST NOT OWN BOTH SIDES OF THE BRIDGE.

Место 2.23 в multi-pass pipeline

02 / local → context bridge

Context pass может изменить требования к линии, но он не должен задним числом переписывать измерения. Изменяется target/policy или создаётся correction request, после чего владельцы пересчитывают свои результаты.

INPUT / SEMANTIC → LOCAL line candidates (2.19) → LOCAL owner metrics (2.02–2.18) → LOCAL ranking (2.20) → CONTEXT / GLOBAL owners evaluate scene → external ContextDirectiveRef[] → 2.23 validate scope + authority ├─ target-only directive → build immutable effectiveTarget │ → rescore SAME candidates in 2.20 ├─ geometry/render change needed → correction request to OWNER │ → bounded regeneration 2.19 → dirty recompute → 2.20 └─ external candidate selection → record selection ref / reason → return LineContextProjection → future global pipeline continues
PURE

Target projection

Создаёт новый effective target с parent ref. Base target остаётся immutable.

ROUTED

Correction

Если нужен другой stroke/geometry/contact, 2.23 просит соответствующего owner, а не мутирует state.

EXTERNAL

Global selection

Решение выбрать локально второй candidate приходит извне и не маскируется под новый localScore.

ContextDirectiveRef: только внешний контракт

03 / external directive reference

2.23 не владеет универсальной schema overrides. До появления 65.xx он принимает минимальный reference envelope, достаточный для line-side validation и audit.

Input reference

ContextDirectiveRef {
  directiveId: string,
  schemaOwner: string,             // EXTERNAL
  issuedBy: string,                // metric/context/global owner
  authority: "CONTEXT|GLOBAL|HARD_AUTHORITY",
  scope: {
    sceneId,
    candidateIds?: string[],
    lineIds?: string[],
    lineRoles?: string[]
  },
  action:
    "PATCH_LINE_TARGET" |
    "REQUEST_LINE_CORRECTION" |
    "SELECT_CANDIDATE" |
    "EXCLUDE_CANDIDATE",
  payloadRef | payload,
  justificationRefs: string[],
  confidence: 0..1,
  provenance,
  version
}

Line-side validation

accept only if:
  directiveId present
  issuedBy present
  authority explicit
  scope intersects current scene / candidate / line
  action in supported line adapter actions
  justificationRefs non-empty
  provenance present

otherwise:
  ignoredDirectives.push({
    directiveId,
    reason
  })
Не временный 65.xx. 2.23 не определяет universal priority stack, exception cost, override budget или generic conflict resolution. Поля здесь — transport envelope. Общая semantics overrides остаётся DEFERRED.

Immutable target projection

04 / effective target

Context может изменить способ интерпретации уже измеренных line metrics, но не сами owner values. Именно поэтому основной безопасный механизм — patch explicit target, а затем повторно вызвать 2.20.

Allowed target patches

LineTargetPatch {
  requiredGroups?: + / - group,
  optionalGroups?: + / - group,
  disabledGroups?: + / - group,
  semanticMultipliers?: {groupOrMetric: value},
  styleMultipliers?: {groupOrMetric: value},
  groupVoteCaps?: {group: value},
  requiredEvidencePolicy?: enum
}

Только поля, которые 2.20 уже понимает как target/policy. Новых metric values patch не создаёт.

Forbidden patch

FORBIDDEN:
  MetricResult.value = ...
  MetricResult.confidence = ...
  LinePathGeometry.* = ...
  stroke.width = ...
  stroke.color = ...
  global.balance = ...
  localScore = ...
  beautyScore = ...

Если context хочет изменить геометрию/rendering — только correction request владельцу.

effectiveTarget = deepClone(baseTarget) for directive in deterministicApplicableTargetDirectives: validate patch path ∈ ALLOWED_TARGET_PATHS validate finite bounded value / enum apply patch to effectiveTarget append patchTrace(directiveId, path, oldValue, newValue) baseTarget MUST remain byte-equivalent / immutable. owner MetricResult payloads MUST remain unchanged.
DERIVEDeffectiveTarget и trace следуют из base target + внешних directives.
STYLE_PRESETStyle multipliers/caps допустимы только с явным preset provenance.
DEFERREDУниверсальный override budget/priority не определяется здесь.
NO LAWНикакой multiplier не считается универсальной эстетической константой.

Локальный победитель может не стать глобальным

05 / selection semantics

2.20 ранжирует candidates внутри одного line target. Глобальный слой может предпочесть другой candidate из-за отношений, которыми line subsystem не владеет. 2.23 должен сохранить это различие явно.

localWinnerRef = LineSystemScoreResult rank #1 from 2.20 externalWinnerRef = ExternalSelectionDirective.candidateId // optional if externalWinnerRef exists: require candidate exists and is not locally hard-rejected selectedCandidateRef = externalWinnerRef localVsContextDelta = { localWinnerRef, selectedCandidateRef, localRankOfSelected, localScoreOfSelected, externalDecisionRef, justificationRefs } else: selectedCandidateRef = localWinnerRef NEVER: overwrite localScore to make externalWinner look locally better.
LOCAL FACT

2.20 stays true

Если A имел localScore .91, а B .87, эти значения сохраняются в audit.

CONTEXT DECISION

B can still be selected

Например, внешний hierarchy-owner сообщает, что A конфликтует с доминантой всей сцены.

NOT ALLOWED

No hidden remix

Нельзя тайно сделать B.localScore=.93 добавив внутри 2.23 global hierarchy.

Context → owner-routed correction

06 / foreign mutation barrier

Глобальный context часто не просто выбирает candidate, а требует изменить линию. 2.23 переводит это в typed request к существующему owner.

Context asks forTarget owner2.23 output
Линия слишком тяжёлая относительно доминанты сцены2.06 / 2.16Correction request: уменьшить visual-weight target / contrast / opacity через owner.
Connector мешает объекту или пересекает protected region2.09 / 2.10 / 2.11 / 2.19Request reroute / contact correction; bounded regeneration by 2.19.
Divider должен поддержать новый grid/context2.13 / 2.14Request updated grid/boundary target; geometry mutation остаётся у owner/generator.
Seam/crop должен учитывать изображение2.22 + future image/global ownersRequest new seam/crop intent or derived geometry; 2.23 не решает image composition.
Нужно другое глобальное eye-flowfuture global flow ownerGlobal owner формулирует directive; 2.08 остаётся только local cue owner.

CorrectionRequest envelope

LineContextCorrectionRequest {
  requestId,
  sourceDirectiveId,
  targetOwner: "Compo2.xx",
  targetCandidateId,
  targetLineId?,
  requestedEffect,          // semantic request, NOT mutation command
  targetPatch?,             // owner-owned target only
  constraints[],
  justificationRefs[],
  seedForkPolicy: "DETERMINISTIC",
  provenance: "DERIVED"
}
NO FOREIGN MUTATION. Нельзя отправить set controlPoint=(x,y), strokeWidth=3 или move endpoint как приказ чужому state. Request описывает желаемый эффект/constraint; owner сам решает допустимое изменение по своему API.

Conflicts: не изобретать универсальный resolver

07 / defer generic override logic

До темы 65 конфликт двух внешних directives не должен разрешаться скрытой эвристикой внутри line subsystem.

Независимые patches

D1: disable GRID_RELATION
D2: styleMultiplier.COLOR_TONE = .8

→ deterministic order by directiveId/version
→ both applied
→ trace keeps both

Conflict

D1: require GRID_RELATION
D2: disable GRID_RELATION

→ status = "context_conflict"
→ unresolvedConflicts += [D1,D2]
→ NO silent last-write-wins
→ request external resolver
conflict if two applicable directives write incompatible values or mutually exclusive membership state to the same canonical target path. NO RESOLUTION BY: higher confidence // unless external generic resolver says so higher issuedBy rank // not owned here later timestamp // not a design principle random seed // forbidden 2.23 may sort conflicts deterministically for audit. 2.23 may NOT decide the generic winner.

Edge cases и invariants

08 / safety cases

Context integration — место, где проще всего нечаянно сломать ownership. Поэтому особые случаи фиксируются как контракт, а не как implementation trivia.

CasePolicy
Нет external directiveseffectiveTarget == baseTarget; локальный winner остаётся selectedCandidateRef.
Directive scope не пересекаетсяIgnored + audit reason; никакого влияния.
Directive без justification/provenanceInvalid for application; diagnostic-only.
Patch пытается изменить owner metricReject directive path; MetricResult immutable.
Patch делает N/A группу required, но evidence неприменим2.20 применяет свою requiredEvidencePolicy; 2.23 не инжектит value=0.
External selection указывает hard-rejected candidateReject selection directive; hard feasibility имеет приоритет.
External winner локально #2Разрешено; сохранить local rank/score и external justification отдельно.
Два конфликтующих directivescontext_conflict; ждём external resolver.
Context требует geometry mutationТолько correction request owner; source candidate immutable.
Global metric отсутствуетНе угадывать; deferred/missing context ref, а не zero.
2.22 seam descriptor доступенМожно передать внешнему context owner как descriptor; он не становится global score.
Повтор pass с теми же refs/versionProjection и trace детерминированы.

Визуальная лаборатория: local ≠ global

09 / visual reference

Один и тот же набор line candidates может иметь локального победителя A, но внешний контекст обоснованно выбрать B. Важно не переписать локальную историю задним числом.

LOCAL PASS · 2.20 GLOBAL CONTEXT · EXTERNAL A · localScore .91 · rank #1 B · localScore .87 · rank #2 DOMINANT SECONDARY A clashes with protected hierarchy B selected by EXTERNAL authority A stays local rank #1 in audit
local winnercontext selectionexternal scene
LOCAL FACT

Не переписываем прошлое

2.20 продолжает утверждать: в своём локальном target A лучше B. Это полезная информация даже после внешнего выбора B.

GLOBAL AUTHORITY

Выбор B хранится отдельно

2.23 записывает externalSelectionRef, justification refs и delta между local rank и context selection.

CORRECTION LOOP

Можно вернуться в line subsystem

Если нужен новый A′, внешний context формулирует directive → 2.23 маршрутизирует correction → 2.19 regenerates → 2.20 rescoring.

Live projection demo

Choose a context scenario.

Детерминированные integration tests

10 / inline JS tests

2.21 владеет полным regression suite темы линии; эти tests проверяют только invariants самого context adapter 2.23.

Tests not run yet.

DATA FOR LAYOUT ENGINE

11 / machine contract

Machine-readable integration contract. Он намеренно описывает только line-side adapter и явно резервирует глобальные функции будущим owners.

{
  "module": "Compo 2.23",
  "name": "line_global_context_adapter",
  "version": "1.1-corrective",
  "scope": "line-side context/global integration protocol: immutable target projection, external selection trace and owner-routed corrections",
  "consumes": [
    "Compo2.19.LineStructureCandidate[]",
    "Compo2.20.LineSystemScoreResult[]",
    "Compo2.22.MaskCropSeamResult[]?",
    "Compo2.20.LineSystemTarget",
    "ContextDirectiveRef[] from external owners",
    "ExternalSelectionDirective?",
    "ExternalContextMetricRef[]",
    "LineContextPolicy",
    "Compo0.seed/lineage"
  ],
  "provides": [
    "LineContextProjection",
    "lineContext.effectiveTarget",
    "lineContext.patchTrace",
    "lineContext.overrideApplicationTrace",
    "lineContext.recomputePlan",
    "LineContextCorrectionRequest[]",
    "localVsContextDelta",
    "ignoredDirectives[]",
    "unresolvedConflicts[]"
  ],
  "owns_metrics": [],
  "descriptors_only": [
    "lineContext.patchTrace",
    "lineContext.overrideApplicationTrace",
    "lineContext.recomputePlan",
    "localVsContextDelta",
    "deferredGlobalRefs",
    "audit"
  ],
  "hard_constraints": [
    "global metrics are never recomputed by 2.23",
    "2.20 localScore is never overwritten by context selection",
    "base target and owner MetricResults are immutable",
    "foreign geometry/render mutation is forbidden",
    "hard-rejected candidate cannot be externally selected",
    "unsupported or unauthorised directive is ignored with audit",
    "conflicting generic overrides are not silently resolved"
  ],
  "soft_constraints": [
    "non-conflicting target patches may be composed deterministically",
    "target patch paths are allow-listed",
    "context corrections are expressed as desired effects/constraints",
    "same refs/version/seed produce same projection trace"
  ],
  "preferences": [
    "prefer target projection before geometry correction when sufficient",
    "preserve local ranking facts even when external selection differs",
    "retain full provenance and justification references",
    "minimize dirty recompute to affected line owners"
  ],
  "overrides_allowed_by": [
    "external context/global authority",
    "future Compo48 global pipeline",
    "future Compo49 global scorer",
    "future Compo65 rule override system"
  ],
  "initial_heuristics": {},
  "style_preset_values": {
    "allowed": "only through fields already accepted by Compo2.20 target/policy",
    "provenance": "STYLE_PRESET"
  },
  "allowed_target_patch_paths": [
    "requiredGroups",
    "optionalGroups",
    "disabledGroups",
    "semanticMultipliers.*",
    "styleMultipliers.*",
    "groupVoteCaps.*",
    "requiredEvidencePolicy"
  ],
  "directive_actions": [
    "PATCH_LINE_TARGET",
    "REQUEST_LINE_CORRECTION",
    "SELECT_CANDIDATE",
    "EXCLUDE_CANDIDATE"
  ],
  "context_projection_policy": {
    "base_target_immutable": true,
    "metric_values_immutable": true,
    "non_conflicting_patch_order": "directiveId|version lexical deterministic",
    "conflicting_patch": "CONTEXT_CONFLICT_UNRESOLVED",
    "generic_priority_resolution": "DEFERRED_TO_COMPO65"
  },
  "selection_policy": {
    "local_winner_owner": "Compo2.20",
    "global_selection_owner": "EXTERNAL/FUTURE_GLOBAL_SOLVER",
    "external_selection_may_choose_local_rank_gt_1": true,
    "external_selection_may_choose_hard_rejected": false,
    "local_score_rewrite": "FORBIDDEN"
  },
  "correction_policy": {
    "direct_foreign_mutation": "FORBIDDEN",
    "request_target": "existing line owner 2.02-2.18 / 2.22 or orchestrator 2.19",
    "orchestrator": "Compo2.19",
    "recompute": "dirty owners then Compo2.20 rescore",
    "seed_fork": "deterministic"
  },
  "deferred_inputs": [
    "Compo48.xx global multi-pass pipeline/convergence",
    "Compo49.xx global metric aggregation/ranking",
    "Compo65.xx universal override schema/budget/conflict resolver",
    "future global balance/hierarchy/eye-flow/negative-space owners"
  ],
  "recompute_when": [
    "applicable target directive set/version changes",
    "external selection directive changes",
    "owner correction changes candidate/metrics",
    "base line target changes",
    "external authority/provenance validation changes"
  ],
  "tests": [
    "C01_NO_CONTEXT_IDENTITY",
    "C02_BASE_TARGET_IMMUTABLE",
    "C03_METRIC_VALUE_IMMUTABLE",
    "C04_SCOPE_MISMATCH_IGNORED",
    "C05_MISSING_AUTHORITY_IGNORED",
    "C06_MISSING_JUSTIFICATION_IGNORED",
    "C07_ALLOWED_TARGET_PATCH",
    "C08_FORBIDDEN_METRIC_PATCH",
    "C09_NON_CONFLICTING_PATCH_DETERMINISM",
    "C10_CONFLICT_NOT_LAST_WRITE_WINS",
    "C11_NA_NOT_ZERO",
    "C12_LOCAL_WINNER_DEFAULT_SELECTION",
    "C13_EXTERNAL_CAN_SELECT_LOCAL_SECOND",
    "C14_LOCAL_SCORE_NOT_REWRITTEN",
    "C15_HARD_REJECT_SELECTION_FORBIDDEN",
    "C16_CORRECTION_ROUTES_TO_OWNER",
    "C17_FOREIGN_MUTATION_REJECTED",
    "C18_DIRTY_RECOMPUTE_TARGETED",
    "C19_GLOBAL_METRIC_REFERENCE_ONLY",
    "C20_2_22_DESCRIPTOR_NOT_GLOBAL_SCORE",
    "C21_NO_BEAUTYSCORE",
    "C22_COMPO48_49_65_DEFERRED",
    "C23_REPEATABLE_TRACE",
    "C24_NO_DIRECTIVE_NO_RESCORE",
    "C25_CANONICAL_HANDOFF_TYPES"
  ],
  "finality": "LINE_CONTEXT_ADAPTER_ONLY",
  "invariants": [
    "ONE_METRIC_ONE_OWNER",
    "N_A_NOT_ZERO",
    "LOCAL_NOT_GLOBAL",
    "GEOMETRY_NOT_INTERPRETATION",
    "DESCRIPTOR_NOT_SCORE",
    "NO_BEAUTYSCORE",
    "NO_FOREIGN_MUTATION",
    "GLOBAL_DECISION_DOES_NOT_REWRITE_LOCAL_FACTS"
  ]
}
ARCHITECTURE CHECKPOINT · 2.23 завершает тему линии как integration adapter: локальные facts остаются у 2.01–2.22, generation — у 2.19, local ranking — у 2.20, regression suite — у 2.21. 2.23 владеет только line-side context projection / trace / correction routing. Global pipeline, global scoring и generic overrides остаются зарезервированы за 48.xx, 49.xx и 65.xx. GLOBAL DECISION NEVER REWRITES LOCAL FACTS.
VISITS / ...