COMPO · 29.03 · ORIENTATION / TEXTURE / STYLE

Wrap angles.
Keep appearance evidence explicit.

29.03 закрывает последние feature channels Topic 29 перед clustering: ORIENTATION сравнивается циклически только внутри одного explicit period/frame contract, а TEXTURE_STYLE использует owner-normalized comparator evidence для конкретного feature slot. Никакой cross-channel агрегации пока нет.

Module29.03
Progress4/5 local
ChannelsORIENTATION · TEXTURE_STYLE
Relationssymmetric
Metricsnone
Next29.04 only

29.03 owns the final two channel-local comparators

29.00 remains immutable; 29.01 and 29.02 remain independent. This module only materializes ORIENTATION and TEXTURE_STYLE distances for explicit pairs.

00 / contract
immutable 29.00 SimilarityFeatureSchema + explicit unordered pair request + exact same channel / same feature slot + ORIENTATION angle evidence OR TEXTURE_STYLE comparator evidence → channel-local feature distance → symmetric SimilarityRelation NO 180°/360° inference NO frame alignment inference NO texture/style metric inference NO cross-channel aggregation NO thresholding NO clustering NO scoring

Orientation lives on a cycle, not a line

Angles near the wrap boundary can be close. For a 360° period, 10° and 350° differ by 20°, not 340°.

01 / cyclic distance
delta = mod(|a-b|, period) wrapped = min(delta, period-delta) normalizedDistance = wrapped / (period/2) range = [0,1] 10° ↔ 350° with period 360°: delta = 340° wrapped = 20° distance = 20 / 180 ≈ 0.111111

Wrap-aware geometry

10°350° 20° wrapped linear subtraction would be wrong here

The period is explicit evidence

An orientation may represent a directed heading or an undirected axis. 29.03 never assumes whether the period should be 360°, 180°, 2π or an owner-defined cycle.

02 / period firewall

period = 360°

directed-cycle contract may use 360°

period = 180°

axis contract may use 180°
Heuristic ≠ lawWhich period is meaningful belongs to the upstream orientation owner, not to 29.03.

Same numeric angle in different frames is N_A

0° relative to image x-axis and 0° relative to a local object frame are not silently comparable. Frame identity and owner must match exactly.

03 / frame compatibility
OK

same frame + same period + same unit

Cyclic distance is defined.

N_A

different frame / period / unit

No automatic alignment, reconciliation or conversion.

Texture/style comparison remains owner-normalized

TEXTURE_STYLE is one schema channel with explicit slots and semantic kinds. The comparator owner supplies a normalized [0,1] distance and its contract.

04 / appearance evidence
feature A

TEXTURE_STYLE · exact slot

+
feature B

same slot

→
comparator evidence

TEXTURE / STYLE / OWNER_DEFINED

→
29.03 distance

0 ≤ d ≤ 1

TEXTURE

Surface pattern

Comparator semantics remain explicit.

STYLE

Appearance language

Style evidence is not forced into texture semantics.

OWNER_DEFINED

Named subtype

Allowed only with an explicit semantic-kind name.

Texture and style slots do not cross silently

A subject may have both `texture` and `style` features. The same-channel relationship does not authorize comparing one slot to another.

05 / slot identity

Two slots, two comparison lanes

A.texture A.style B.texture B.style cross-slot forbidden

`SimilarityRelation` still carries no group verdict

All six Topic29 channels can now produce local distance relations, but no module before 29.04 may turn them into clusters.

06 / relation shell

ORIENTATION or TEXTURE_STYLE relation

SimilarityRelation channel = ORIENTATION | TEXTURE_STYLE distanceValue = descriptor similarityScore = null thresholdDecision = null clusterRefs = []

Zero remains distinct from missing evidence

Same phase modulo period or comparator equality can produce 0. Missing feature, frame mismatch or period mismatch produces N_A.

OK

distance = 0

Valid equality under the explicit channel contract.

N_A

frame / period mismatch

No numeric substitute.

INVALID

period ≤ 0

Malformed orientation evidence.

All six feature channels are now covered

29.04 can consume channel-local relations from 29.01, 29.02 and 29.03 and build explicit multi-channel groups without erasing signal provenance.

08 / Topic29 frontier
29.01

SHAPE · SIZE

+
29.02

COLOR · TONE

+
29.03

ORIENTATION · TEXTURE_STYLE

→
29.04

multi-channel groups + tests

Stop boundaryThis artifact does not choose weights, thresholds or clusters. Those decisions belong to 29.04.

29.03 regression suite

Tests cover wrap-aware orientation distance, explicit period/unit/frame compatibility, texture/style semantic kinds, exact slots, zero/N_A separation, immutable 29.00 schema and strict absence of cross-channel aggregation, clustering and scoring.

09 / runtime
Tests not run yet.

DATA FOR LAYOUT ENGINE

Canonical machine contract for Topic29 orientation/texture/style layer.

10 / machine
{
  "module": "Compo 29.03",
  "name": "orientation_texture_style_similarity",
  "version": "1.0-canonical",
  "canonical_main_title": "Orientation/texture/style similarity",
  "topic": "29_СХОДСТВО_И_ПОВТОРЯЕМОСТЬ",
  "scope": "EXPLICIT_UNORDERED_PAIR_COMPARISONS_FOR_ORIENTATION_AND_TEXTURE_STYLE_CHANNELS_OVER_IMMUTABLE_29_00_FEATURE_SCHEMA_WITH_CHANNEL_LOCAL_DISTANCES_ONLY",
  "main_topic_contract": {
    "topic_title": "Сходство и повторяемость",
    "topic_goal": "Измеряет сходство по независимым каналам — shape, size, color, tone, orientation, texture/style — и формирует similarity groups без потери источника сигнала.",
    "expected_output": "SimilarityRelation[], feature distances, similarity clusters",
    "planned_files": [
      "29.00 Similarity feature schema",
      "29.01 Shape/size similarity",
      "29.02 Color/tone similarity",
      "29.03 Orientation/texture/style similarity",
      "29.04 Multi-channel groups and tests"
    ]
  },
  "ownership": {
    "owner": "Compo29.03",
    "owns": [
      "SimilarityOrientationTextureStylePairRequest",
      "SimilarityOrientationValueEvidence",
      "SimilarityTextureStyleDistanceEvidence",
      "SimilarityTextureStyleSemanticKind taxonomy",
      "SimilarityFeatureDistanceDescriptor for ORIENTATION/TEXTURE_STYLE",
      "SimilarityRelation for ORIENTATION/TEXTURE_STYLE",
      "SimilarityOrientationTextureStyleRelationSet",
      "SimilarityOrientationTextureStyleAttachment",
      "canonical unordered subject-pair identity",
      "exact same-channel feature binding",
      "exact same-slot comparison rule",
      "cyclic orientation-distance derivation",
      "orientation unit/period/frame compatibility validation",
      "owner-normalized texture/style-distance validation",
      "semantic-kind preservation for texture/style comparator evidence",
      "symmetric relation materialization",
      "zero-distance semantics",
      "bounded explicit pair resolution",
      "non-mutating correction request"
    ],
    "does_not_own": [
      "feature extraction",
      "orientation extraction from geometry or pixels",
      "automatic 180° vs 360° period selection",
      "automatic angle unit conversion",
      "texture descriptor generation",
      "style descriptor generation",
      "texture/style comparator implementation internals",
      "automatic texture/style metric selection",
      "shape/size similarity — Compo29.01",
      "color/tone similarity — Compo29.02",
      "multi-channel aggregation — Compo29.04",
      "similarity thresholds — Compo29.04",
      "similarity clusters — Compo29.04",
      "cross-channel weighting — Compo29.04",
      "automatic pair Cartesian product",
      "proximity grouping — Topic28",
      "attention flow — Topic27",
      "universal similarity quality",
      "universal beautyScore"
    ]
  },
  "supported_channels": [
    "ORIENTATION",
    "TEXTURE_STYLE"
  ],
  "texture_style_semantic_kinds": [
    "TEXTURE",
    "STYLE",
    "OWNER_DEFINED"
  ],
  "distance_kinds": [
    "NORMALIZED_CYCLIC_ORIENTATION_DISTANCE",
    "OWNER_NORMALIZED_TEXTURE_STYLE_DISTANCE"
  ],
  "distance_semantics": {
    "orientation": {
      "source": "explicit angleValue + angleUnit + periodValue + orientationFrameRef evidence per feature",
      "formula": "delta = mod(abs(a-b), period); wrapped = min(delta, period-delta); normalizedDistance = wrapped / (period/2)",
      "range": "[0,1]",
      "zero": "same phase modulo the explicit period",
      "one": "half-period separation under the explicit period contract",
      "required_compatibility": "same angleUnit, same periodValue, same orientationFrameRef and owner",
      "period_inference": "NONE",
      "unit_conversion": "NONE",
      "perceptual_law_claim": false
    },
    "texture_style": {
      "source": "explicit owner-qualified comparator evidence",
      "range": "[0,1]",
      "zero": "identical under the named comparator contract",
      "one": "maximum mismatch only under comparator normalization contract",
      "semantic_kind": "TEXTURE, STYLE or explicit OWNER_DEFINED",
      "slot_binding": "exact featureSlotRef required",
      "universal_metric_claim": false
    },
    "relation": {
      "pair_identity": "unordered canonical subject pair A↔B",
      "symmetric": true,
      "same_channel_required": true,
      "same_feature_slot_required": true,
      "similarityScore": null,
      "thresholdDecision": null,
      "clusterMembership": "DEFERRED_TO_29_04"
    }
  },
  "policy": {
    "max_pair_requests": [
      1,
      131072
    ],
    "max_orientation_value_evidence": [
      0,
      262144
    ],
    "max_texture_style_distance_evidence": [
      0,
      131072
    ],
    "overflow": "N_A_NO_TRUNCATION",
    "duplicate_request_ref": "INVALID",
    "duplicate_channel_pair_slot_request": "INVALID",
    "duplicate_evidence_ref": "INVALID",
    "auto_pair_cartesian": false,
    "auto_orientation_extraction": false,
    "auto_orientation_period_selection": false,
    "auto_angle_unit_conversion": false,
    "auto_orientation_frame_alignment": false,
    "auto_texture_style_metric_selection": false,
    "auto_texture_style_distance_computation": false,
    "auto_cross_slot_comparison": false,
    "auto_cross_channel_aggregation": false,
    "auto_thresholding": false,
    "auto_clustering": false,
    "auto_scoring": false
  },
  "status_semantics": {
    "OK": "29.00 feature lineage resolves and requested ORIENTATION/TEXTURE_STYLE comparison produces a valid symmetric channel-local distance",
    "N_A": "feature/evidence missing, subject/feature/slot mismatch, orientation unit/period/frame mismatch, or bounds overflow",
    "INVALID": "malformed request/evidence, duplicate identity, self-pair, nonpositive orientation period, unsupported channel/semantic kind, or invalid upstream schema",
    "zero": "distance 0 is a valid equality observation under the channel contract and is never substituted for N_A"
  },
  "firewalls": [
    "orientation distance != orientation similarity score",
    "texture/style distance != texture/style similarity score",
    "distance zero != N_A",
    "orientation distance one != universal maximum directional difference",
    "orientation period != automatically 180 or 360 degrees",
    "orientation frame != attention direction",
    "same angle number in different frames != comparable orientation",
    "same texture/style slot != same texture/style value",
    "TEXTURE semantic kind != STYLE semantic kind",
    "feature distance != threshold decision",
    "SimilarityRelation != similarity cluster",
    "ORIENTATION relation != TEXTURE_STYLE relation",
    "orientation and texture/style relations cannot be averaged automatically",
    "pair request != Cartesian pair generation",
    "same-slot comparison != cross-slot inference",
    "angle-unit mismatch != automatic conversion",
    "period mismatch != automatic reconciliation",
    "missing orientation != angle zero",
    "Topic29 similarity != Topic28 proximity",
    "Topic29 similarity relation != Topic28 neighbor relation",
    "Topic29 orientation similarity != Topic27 attention flow",
    "N_A != 0",
    "INVALID != 0",
    "descriptor != score",
    "local != global",
    "geometry != interpretation",
    "heuristic != law",
    "no universal similarity threshold",
    "no universal beautyScore"
  ],
  "owns_metrics": [],
  "independent_numeric_votes": 0,
  "topic29ProgressAfterThisModule": "4/5 local",
  "next_module": "Compo 29.04 — Multi-channel groups and tests",
  "topic30_started": false,
  "publication": "NOT_VERIFIED"
}
VISITS / ...