COMPO · 21.04 · APPROXIMATE SYMMETRY / SCORING

Tolerance is explicit.
Intent stays visible.

21.04 завершает Topic 21: переводит явные position, mass, shape и color discrepancies в нормализованные symmetry errors только через explicit tolerance rules, поддерживает controlled intentional breaks и выдаёт один composite local target-fit vote. POSITION из 21.03 не считается второй раз: это alias того же residual из 21.01.

ModuleCompo 21.04
Input21.00–21.03
Toleranceexplicit only
Intentpreserve / break
Votesexactly 1
Topic5/5 local

Approximation after exact descriptors

00 / contract
21.01 mirror residuals
+ 21.02 pair / axis mass differences
+ 21.03 SHAPE / COLOR comparisons
+ explicit owner-qualified approximation rules
→ SymmetryErrorDescriptor[]
→ explicit intent-aware target bands
→ four family component MetricResults
→ one composite symmetry.system.localTargetProfileFit

NO hidden epsilon
NO second POSITION vote
NO beautyScore
NO automatic geometry mutation

One final owner, upstream identities preserved

01 / ownership
OWNS

21.04

Approximation rules, normalized symmetry errors, explicit intent targets, four component MetricResults, one composite vote and final Topic21 tests.

DOES NOT OWN

Upstream + foreign

Axis identity, mirror pairs, visual-mass semantics, raw shape/color extraction, asymmetric balance, radial balance or any foreign mutation.

Five source kinds, four scoring families

02 / source discipline
Source kindOwnerFamilyRaw discrepancy
MIRROR_POSITIONCompo21.01POSITIONresidualDistance
PAIR_MASSCompo21.02MASSnormalizedPairMassDifference
AXIS_MASSCompo21.02MASSnormalizedSideMassDifference
SHAPE_CHANNELCompo21.03SHAPEcomparisonValue / exactMatch
COLOR_CHANNELCompo21.03COLORcomparisonValue / exactMatch
Double-count firewall: Compo21.03 POSITION is the same mirror residual adapted as a channel descriptor. It may be checked for lineage, but 21.04 does not materialize it as another independent error or vote.

Approximate means normalized against a declared tolerance

03 / math
NUMERIC

Explicit tolerance

e = min(1, rawDifference / tolerance)
closeness = 1 − e

tolerance > 0
raw = tolerance → WITHIN_TOLERANCE
BOOLEAN

Exact category semantics

exact match → error 0
mismatch → error 1

No invented numeric color/shape distance.

Normalized error is a descriptor. It is not an aesthetic penalty and not a MetricResult.

Intentional violation is a target, not an exception hack

04 / intent
SYMMETRY_PRESERVED

Near zero

The target band may request exact or approximate symmetry.

INTENTIONAL_BREAK

Nonzero by design

A declared nonzero error band can be the intended local target and can score full fit.

STYLE_DEFINED

Owner-defined

The style/task owner supplies the band. 21.04 does not infer taste.

Composite-first scoring

05 / MetricResult
Metric keyCompositeIndependent vote
symmetry.target.componentFit.positionfalsefalse
symmetry.target.componentFit.massfalsefalse
symmetry.target.componentFit.shapefalsefalse
symmetry.target.componentFit.colorfalsefalse
symmetry.system.localTargetProfileFittruetrue
component fit = explicit item-weighted mean of inclusive target-band fits
composite = explicit family-weighted mean of APPLY components

Exactly one independent numeric vote.
scoringGroup = symmetry-local

N_A stays different from zero

06 / status
0 errorValid exact observation.
fit = 0Valid target mismatch with complete evidence.
N_AMissing selected evidence, explicit family IGNORE, empty rule set or bounded overflow. Never imputed as 0.
INVALIDMalformed rule/target or contradictory owner/root lineage.

Topic 21 stops before asymmetric balance

07 / boundaries
21.00Axis candidates.
21.01Mirror correspondence / SymmetryRelation.
21.02Mass symmetry descriptors.
21.03Shape/color/position channel descriptors.
21.04Approximation, intent-aware local scoring and final tests.
Topic22Asymmetric balance, visual center of mass, torque-like moments and counterweights. Separate owner.

Symmetry is not universal quality

08 / firewalls
exact symmetry != automatically desirable
nonzero error != automatically bad
intentional break may fit target = 1
normalizedSymmetryError != beauty penalty
approximateSymmetryCloseness != beautyScore
21.03 POSITION != second position vote
pair mass + axis mass → one MASS family component
target mismatch 0 != N_A

local != global
descriptor != score
correction request != mutation
no universal beautyScore

CANON → LAB → DATA → IDEAS

09 / mandatory hooks
IDEAS_REFS[]Approximation and intentional-break studies.
DATA_CAPTURE[]Raw errors, rules, normalized errors and target fits.
DEFERRED_SEMANTIC_INPUTS[]Topic22/23 and global quality remain downstream.
HUMAN_FEEDBACK_HOOKS[]Tolerance, intent and lineage corrections.
CONFLICT_PRIORITY_ASSUMPTIONS[]No hidden family priority.
LAB_HOOKS[]Human tolerance and false-error studies.

21.04 final regression suite

10 / deterministic tests

Tests cover explicit tolerances, owner-qualified source adapters, duplicate-position firewall, normalized error math, category handling, intentional-break target bands, family-level anti-double-counting, MetricResult constitution, exact one-vote rule, N_A/zero semantics, immutable attachments and Topic22 boundary.

Tests not run yet.

DATA FOR LAYOUT ENGINE

11 / machine contract
{
  "module": "Compo 21.04",
  "name": "approximate_symmetry_scoring_tests",
  "version": "1.0-canonical",
  "canonical_main_title": "Approximate symmetry, scoring/tests",
  "topic": "21_СИММЕТРИЧНЫЙ_БАЛАНС",
  "scope": "EXPLICIT_SOURCE_SCOPED_APPROXIMATE_SYMMETRY_NORMALIZATION_INTENT_AWARE_LOCAL_TARGET_SCORING_AND_FINAL_TOPIC21_TESTS_WITHOUT_HIDDEN_TOLERANCE_DOUBLE_COUNTED_POSITION_GLOBAL_BEAUTY_OR_FOREIGN_MUTATION",
  "main_topic_contract": {
    "topic_title": "Симметричный баланс",
    "topic_goal": "Измеряет осевую и зеркальную симметрию по позиции, форме, массе и цвету, включая approximate symmetry и намеренные нарушения.",
    "expected_output": "SymmetryRelation[], axis candidates, symmetry errors",
    "planned_files": [
      "21.00 Symmetry axis model",
      "21.01 Mirror correspondence",
      "21.02 Mass symmetry",
      "21.03 Channel symmetry: shape/color/position",
      "21.04 Approximate symmetry, scoring/tests"
    ]
  },
  "ownership": {
    "owner": "Compo21.04",
    "owns": [
      "SymmetryApproximationSourceKind taxonomy",
      "SymmetryApproximationNormalizationMode taxonomy",
      "SymmetryIntentTag taxonomy",
      "SymmetryApproximationRule",
      "SymmetryErrorDescriptor",
      "SymmetryErrorSetPolicy",
      "SymmetryErrorSet",
      "ApproximateSymmetryAttachment",
      "SymmetryLocalTargetItem",
      "SymmetryLocalTargetProfile",
      "four Topic21 component MetricResults",
      "one composite MetricResult symmetry.system.localTargetProfileFit",
      "SymmetryLocalEvaluationSet",
      "SymmetryScoringAttachment",
      "explicit tolerance normalization for position/mass/shape/color evidence",
      "intent-aware target bands including explicit intentional-break targets",
      "final Topic21 regression tests"
    ],
    "does_not_own": [
      "symmetry subject/frame/axis identity — Compo21.00",
      "mirror pairing/reflection geometry/SymmetryRelation identity — Compo21.01",
      "visual mass definition or mass evidence — Compo4 / Compo21.02",
      "shape/color/position raw channel extraction — foreign owners / Compo21.03 adapters",
      "21.03 POSITION as a second independent position vote — prohibited duplicate of 21.01 residual",
      "asymmetric balance / visual centroid / torque-like moments / counterweights — Topic22",
      "radial or rotational balance — Topic23",
      "global beautyScore",
      "final-layout ranking",
      "foreign geometry/style/color/semantic mutation"
    ]
  },
  "consumes": [
    "valid Compo21.00 SymmetryAxisSystemSeed lineage",
    "valid Compo21.01 SymmetryRelation records and residualDistance",
    "valid Compo21.02 PairMassSymmetryDescriptor / AxisMassSymmetryDescriptor",
    "valid Compo21.03 SHAPE/COLOR ChannelSymmetryDescriptor records",
    "optional Compo21.03 POSITION descriptors for alias-lineage diagnostics only, never a second scoring component",
    "explicit SymmetryApproximationRule records",
    "explicit SymmetryLocalTargetProfile"
  ],
  "provides": [
    "SymmetryErrorDescriptor[]",
    "SymmetryErrorSet",
    "ApproximateSymmetryAttachment",
    "SymmetryLocalEvaluationSet",
    "four component MetricResults",
    "one composite MetricResult symmetry.system.localTargetProfileFit",
    "SymmetryScoringAttachment",
    "final Topic21 tests"
  ],
  "owns_metrics": [
    "symmetry.target.componentFit.position",
    "symmetry.target.componentFit.mass",
    "symmetry.target.componentFit.shape",
    "symmetry.target.componentFit.color",
    "symmetry.system.localTargetProfileFit"
  ],
  "independent_numeric_votes": {
    "count": 1,
    "key": "symmetry.system.localTargetProfileFit",
    "owner": "Compo21.04",
    "scoringGroup": "symmetry-local",
    "component_metrics_independentVoteAllowed": false,
    "composite_independentVoteAllowed": true
  },
  "approximation_contract": {
    "source_kinds": [
      "MIRROR_POSITION",
      "PAIR_MASS",
      "AXIS_MASS",
      "SHAPE_CHANNEL",
      "COLOR_CHANNEL"
    ],
    "position_duplicate_rule": "Compo21.03 POSITION is an alias of Compo21.01 residualDistance and is never materialized as an independent SymmetryErrorDescriptor in v1",
    "numeric_normalization": "normalizedSymmetryError = min(1, rawDifference / explicitTolerance), tolerance > 0",
    "boolean_normalization": "exact match -> 0; category mismatch -> 1",
    "closeness": "approximateSymmetryCloseness = 1 - normalizedSymmetryError",
    "classification": [
      "EXACT_MATCH",
      "WITHIN_TOLERANCE",
      "OUTSIDE_TOLERANCE"
    ],
    "boundary": "rawDifference == tolerance is WITHIN_TOLERANCE",
    "no_default_tolerance": true
  },
  "target_scoring_contract": {
    "families": [
      "POSITION",
      "MASS",
      "SHAPE",
      "COLOR"
    ],
    "family_mode": "APPLY or IGNORE explicit per family",
    "item_target": "explicit normalized-error band [0,1] plus explicit itemWeight",
    "intent_tags": [
      "SYMMETRY_PRESERVED",
      "INTENTIONAL_BREAK",
      "STYLE_DEFINED"
    ],
    "component_value": "weighted mean of binary inclusive-band item fits inside one family",
    "composite_value": "explicit family-weighted mean of applicable component MetricResults",
    "intentional_break_note": "a nonzero normalized error may score as target fit = 1 when the explicit target band requests a controlled break",
    "evaluationOutcome": "KEEP only; no automatic geometry mutation"
  },
  "metric_result_contract": {
    "fields": [
      "key",
      "owner",
      "value",
      "applicability",
      "confidence",
      "status",
      "provenance",
      "composite",
      "componentOf",
      "dependsOn[]",
      "derivedFrom[]",
      "scoringGroup",
      "independentVoteAllowed",
      "evidence",
      "repairHints[]"
    ],
    "owner": "Compo21.04",
    "scoringGroup": "symmetry-local",
    "componentOf": "symmetry.system.localTargetProfileFit",
    "one_metric_one_owner": true
  },
  "status_semantics": {
    "OK": "explicit compatible upstream source + explicit approximation rule + complete applicable target item lineage",
    "N_A": "missing selected source/error, explicit target family IGNORE, incomplete required evidence, empty explicit rules or bounded overflow; no guessing",
    "INVALID": "malformed rule/profile, incompatible source kind/mode, invalid upstream descriptor, or root/scope lineage mismatch",
    "zero_note": "raw error 0, normalizedSymmetryError 0, closeness 1 and target fit 0 or 1 are valid numbers; none means N_A"
  },
  "critical_firewalls": [
    "approximate symmetry tolerance is explicit; no universal epsilon",
    "normalizedSymmetryError != aesthetic penalty",
    "approximateSymmetryCloseness != beautyScore",
    "exact symmetry != automatically desirable",
    "nonzero symmetry error != automatically bad",
    "intentional symmetry break can be a valid target",
    "21.03 POSITION != second position vote",
    "position scoring source is Compo21.01 mirror residual once",
    "pair mass and axis mass remain inside one MASS component family",
    "shape/color source units are normalized only through explicit owner-qualified tolerances",
    "category mismatch uses explicit boolean normalization only",
    "target mismatch = valid component fit 0, not N_A",
    "family IGNORE = TARGET_DECLARED_NA and leaves composite denominator",
    "missing APPLY evidence = N_A; it is not zero",
    "SymmetryErrorDescriptor != MetricResult",
    "component MetricResults are not independent votes",
    "exactly one independent Topic21 vote",
    "local target fit != global composition quality",
    "reflection symmetry != asymmetric balance",
    "reflection symmetry != radial/rotational balance",
    "no automatic nearest-neighbour matching",
    "no hidden shape/color extraction",
    "no foreign mutation",
    "N_A != 0",
    "INVALID != 0",
    "local != global",
    "geometry != interpretation",
    "descriptor != score",
    "heuristic != law",
    "correction request != foreign mutation",
    "module execution order != rule priority",
    "one metric = one owner",
    "no universal beautyScore",
    "IDEA != CANON",
    "EXPERIMENT != CANON"
  ],
  "IDEAS_REFS": [
    "IDEA-01 study human tolerance bands for approximate reflection symmetry",
    "IDEA-02 study intentional symmetry breaks separately from accidental mismatch",
    "IDEA-03 compare pair-mass and axis-mass evidence without granting two independent votes",
    "IDEA-04 study shape/color tolerance calibration in owner-qualified representation spaces",
    "IDEA-05 collect cases where exact symmetry is intentionally not the preferred target"
  ],
  "DATA_CAPTURE": [
    "scopeRef",
    "snapshotRef",
    "symmetryAxisSystemSeedRef",
    "sourceDescriptorRefByError",
    "sourceKindByError",
    "approximationRuleRefByError",
    "rawDifferenceByError",
    "normalizedSymmetryErrorByError",
    "approximateSymmetryClosenessByError",
    "approximationClassByError",
    "targetItemRefs[]",
    "targetBandByItem",
    "intentTagByItem",
    "componentMetricResultRefs[]",
    "compositeMetricResultRef",
    "status",
    "reasonCode"
  ],
  "DEFERRED_SEMANTIC_INPUTS": [
    "Topic22 asymmetric-balance interpretation",
    "Topic23 radial/rotational balance",
    "global composition quality",
    "final-layout ranking"
  ],
  "HUMAN_FEEDBACK_HOOKS": [
    "correct approximation source kind",
    "correct tolerance rule",
    "correct channel owner",
    "mark position alias duplicate",
    "correct family assignment",
    "correct target band",
    "mark intentional symmetry break",
    "correct item/family weight",
    "correct upstream lineage"
  ],
  "CONFLICT_PRIORITY_ASSUMPTIONS": [
    "serialization order has no scoring priority",
    "confidence does not choose a source winner",
    "exactness does not override explicit intentional-break target",
    "module execution order does not imply family priority",
    "family priority exists only through explicit target weights"
  ],
  "LAB_HOOKS": [
    "approximate reflection perception study",
    "intentional-break study",
    "mass-family redundancy study",
    "shape/color tolerance calibration study",
    "false symmetry-error diagnosis study"
  ],
  "topic21ProgressAfterThisModule": "5/5 local",
  "next_step": "TOPIC21_CLOSING_AUDIT_SEPARATE_STEP",
  "hard_stop": "Do not implement Topic22 in this file."
}
VISITS / ...