Сравниваем массу, не композицию
4.03 отвечает на вопросы «во сколько раз», «кто тяжелее», «насколько близки» и «какая доля массы в наборе». Он не решает, хорошо ли распределены массы.
Pair ratios, log-ratios, relative gaps, ordering, equivalence bands и mass shares.
Уже готовые comparable mass magnitudes, предпочтительно из 4.02.
VISUAL MASS RELATIONS ONLY.
ComparableMassRef
Сравнение допустимо только внутри одной mass calibration/stage/domain системы.
ComparableMassRef
{
objectRef,
massRef,
massValue,
stage:
"INTRINSIC" |
"CROSS_OBJECT_CONTEXTUALIZED",
calibrationDomainRef,
measurementDomainRef,
confidence,
provenance
}Comparable iff
same calibrationDomainRef same calibrationProfileRef same measurementDomainRef same stage massValue finite >= 0 unless: an explicit external normalization adapter has already reconciled the domains.
PairMassRelation
Pair relation хранит несколько разных представлений одной связи; они не должны независимо голосовать в 4.04 как четыре «разных сигнала».
PairMassRelation {
aRef,
bRef,
ratio?,
logRatio,
relativeGap,
pairOrder,
equivalenceClass,
calibrationDomainRef,
measurementDomainRef,
stage,
confidence,
status,
provenance
}
Ratio, log-ratio, relative gap
Log-ratio удобен как симметричный signed descriptor: swapping A/B просто меняет знак.
Ratio
Log ratio
Relative gap
Order и equivalence band
Численные различия меньше tolerance можно считать одной perceptual mass band, но tolerance остаётся эвристикой/калибровкой.
MassOrderingResult
Set ordering использует mass magnitude; equivalence groups сохраняют near-ties, а lexical tie-break нужен только для deterministic serialization.
MassOrderingResult {
comparisonSetRef,
orderedObjectRefs[],
tieGroups[],
massShares[],
stage,
calibrationDomainRef,
measurementDomainRef,
confidence,
status,
provenance
}
Global scale invariance
Если все массы в comparison set умножить на одинаковый положительный коэффициент, relations должны остаться теми же.
Zero mass cases
Нулевая mass может быть валидной — например explicit alpha=0 в 4.01. Но ratio с нулевым denominator нельзя сериализовать как Infinity в canonical JSON.
| A | B | Order | Canonical ratio |
|---|---|---|---|
| 0 | 0 | ZERO_ZERO | N/A |
| >0 | 0 | A_GT_B | N/A; logRatio finite via ε descriptor |
| 0 | >0 | A_LT_B | 0 |
| N/A | any | N_A | N/A |
Confidence
Relation confidence зависит от evidence quality сравниваемых masses, а не от того, насколько ratio далёк от 1.
Mass dominance ≠ hierarchy
Это особенно важно перед будущими global темами.
Heaviest
Максимальная contextual mass в declared comparison set.
Most important
Semantic/visual hierarchy требует отдельного owner и дополнительных signals.
Balanced
Нужны positions, moments/distribution и scene structure, а не только ranked masses.
Relation correction, не mutation
4.03 может сформулировать desired relation, но не знает, какой параметр объекта нужно менять.
MassRelationCorrectionRequest {
comparisonSetRef,
objectRefs[],
requestedRelation:
"INCREASE_A_RELATIVE_TO_B" |
"DECREASE_A_RELATIVE_TO_B" |
"BRING_TO_EQUIVALENCE_BAND" |
"SEPARATE_FROM_EQUIVALENCE_BAND",
currentRelationRef,
targetOwner: "DEFERRED / solver",
constraints[],
provenance
}
Visual Lab
Relations показаны как факты внутри sets, без verdict «хорошо/плохо».
Reference relation tests
Проверяем ratios, symmetry, zero cases, scale invariance, comparability, shares и deterministic ordering.
DATA FOR LAYOUT ENGINE
Machine-readable contract 4.03.
{
"module": "Compo 4.03",
"name": "mass_ratios_ordering_and_relations",
"version": "1.1-corrective",
"scope": "PAIR_AND_SET_RELATIONS_BETWEEN_COMPARABLE_VISUAL_MASS_MAGNITUDES",
"consumes": [
"Compo4.00.VisualMassDescriptor / MassEvidenceStage",
"Compo4.02.CrossObjectContextMassResult as preferred comparison input",
"Compo4.01.ShapeGeometricMassResult? for explicitly intrinsic-only comparisons",
"ComparableMassRef[]",
"MassRelationPolicy",
"StylePreset.massRelationTolerance?"
],
"provides": [
"ComparableMassRef",
"PairMassRelation",
"MassOrderingResult",
"MassEquivalenceBand",
"MassShareDescriptor[]",
"MassRelationSet",
"MassRelationCorrectionRequest[]"
],
"owns_metrics": [
"visualMass.relation.logRatio",
"visualMass.relation.ratio",
"visualMass.relation.relativeGap",
"visualMass.relation.massShare",
"visualMass.relation.orderClass",
"visualMass.relation.equivalenceClass",
"visualMass.relation.confidence"
],
"descriptors_only": [
"visualMass.relation.pairOrder",
"visualMass.relation.rankIndex",
"visualMass.relation.tieGroup",
"visualMass.relation.comparisonSetRef",
"visualMass.relation.inputStage",
"visualMass.relation.calibrationDomainRef",
"visualMass.relation.measurementDomainRef",
"visualMass.relation.status"
],
"comparable_mass_schema": {
"objectRef": "string",
"massRef": "owner-qualified metric ref",
"massValue": "finite >=0",
"stage": "INTRINSIC|CROSS_OBJECT_CONTEXTUALIZED",
"calibrationDomainRef": "required; all compared items must match",
"measurementDomainRef": "required when source may be full/clipped/custom; all compared items must match",
"confidence": "0..1",
"provenance": "object",
"calibrationProfileRef": "required profileId@version; all compared items must match"
},
"pair_relation_schema": {
"aRef": "object ref",
"bRef": "object ref",
"ratio": "A/B; N/A when B≈0 unless both≈0",
"logRatio": "ln((A+epsMass)/(B+epsMass)) for stable signed comparison descriptor",
"relativeGap": "(A-B)/max(A,B,epsMass)",
"pairOrder": "A_GT_B|A_LT_B|EQUIVALENT|ZERO_ZERO|N_A",
"equivalenceClass": "SAME_BAND|DIFFERENT_BAND|N_A",
"confidence": "min/combined source evidence confidence",
"status": "OK|PARTIAL|N_A|INVALID",
"calibrationProfileRef": "uniform profileId@version"
},
"set_relation_schema": {
"comparisonSetRef": "string",
"orderedObjectRefs": "descending mass; stable lexical tie-break inside equivalence band",
"massShares": "mass_i / sum(mass); N/A when total≈0",
"tieGroups": "equivalence-band groups",
"pairRelations": "optional bounded pair relations",
"stage": "uniform across set",
"calibrationDomainRef": "uniform across set",
"measurementDomainRef": "uniform across set",
"confidence": "aggregate evidence confidence",
"status": "OK|PARTIAL|N_A|INVALID",
"calibrationProfileRef": "uniform profileId@version"
},
"relation_math": {
"ratio": "A/B",
"logRatio": "ln(A/B) when both A and B are above massZeroEpsilon; otherwise N/A except ZERO_ZERO state",
"relativeGap": "(A-B)/max(A,B,epsMass)",
"massShare": "A/sum(set)",
"order_by": "massValue descending",
"equivalence_band": "|logRatio| <= equivalenceLogEpsilon",
"scale_invariance": "for positive masses that remain above the declared zero threshold, multiplying every compared mass by the same positive k leaves ratio/logRatio/relativeGap/share/order unchanged"
},
"policy_schema": {
"equivalenceLogEpsilon": "positive finite tolerance",
"massZeroEpsilon": "nonnegative finite numerical threshold",
"allowIntrinsicComparison": "boolean",
"requireSameStage": "true by default",
"requireSameCalibrationDomain": "true",
"requireSameMeasurementDomain": "true",
"maxPairRelations": "bounded implementation budget",
"confidencePolicy": "MIN|GEOMETRIC_MEAN"
},
"semantics": {
"ratio": "magnitude relation only",
"order": "visual mass ordering only",
"equivalent": "within declared tolerance, not geometrically identical",
"massShare": "share of mass inside the declared comparison set only; not scene balance",
"dominant_mass": "if used descriptively, means highest mass in set only; not semantic hierarchy or focal priority",
"tie_break": "stable lexical tie-break is implementation ordering, not perceptual superiority"
},
"hard_constraints": [
"4.03 consumes mass magnitudes and must not reapply contrast/isolation/position/overlap",
"4.03 does not recompute 4.01 area/density or 4.02 contextual mass",
"compared masses must share calibrationDomainRef",
"compared masses must share measurementDomainRef unless an explicit external normalization adapter has already reconciled them",
"mixed INTRINSIC and CROSS_OBJECT_CONTEXTUALIZED stages are incomparable by default",
"ratio/order/share are descriptors, not aesthetic scores",
"massShare is relative only to declared comparison set and is not global balance",
"highest visual mass does not imply semantic hierarchy, importance or focal correctness",
"equivalence tolerance has provenance and is not a universal perceptual law",
"zero-vs-zero pair ratio is N/A with ZERO_ZERO order state, not ratio=1 by fiat",
"zero denominator with positive numerator yields ratio=+INF descriptor only if representation supports it; canonical JSON result should use ratio=null plus order/logRatio evidence rather than non-finite JSON",
"N/A != 0",
"negative space remains Topic5",
"global balance/hierarchy/eye-flow remain future owners",
"target-aware mass scoring remains Compo4.04",
"no beautyScore",
"compared masses must share calibrationProfileRef/profile version, not only canonicalDomainRef",
"positive-mass logRatio uses ln(A/B) without additive epsilon; zero-involved logRatio is N/A to preserve honest scale semantics",
"scale invariance is claimed only while zero/nonzero classification remains unchanged under the declared numerical threshold"
],
"initial_heuristics": {
"equivalence_log_epsilon": {
"value": 0.08,
"provenance": "INITIAL_HEURISTIC"
},
"mass_zero_epsilon": {
"value": 1e-12,
"provenance": "IMPLEMENTATION_HEURISTIC"
},
"max_pair_relations": {
"value": 256,
"provenance": "IMPLEMENTATION_HEURISTIC"
}
},
"correction_policy": {
"foreign_mass_mutation": "FORBIDDEN",
"incomparable_calibration_domain": "request 4.04 calibration adapter/profile",
"mixed_stage": "request upstream stage alignment via 4.00/4.02",
"mixed_measurement_domain": "request source-domain alignment before comparison",
"mass_value_issue": "route to 4.01/4.02/source local-weight owner",
"desired_mass_relation_change": "emit relation correction request; actual object/color/spacing/transform change belongs to relevant owner",
"balance_issue": "route to future balance/global owner",
"hierarchy_issue": "route to future hierarchy/semantic owner"
},
"deferred_inputs": [
"Compo4.04 calibration/target-aware scoring/regression",
"Topic5 positive/negative space",
"future global balance",
"future hierarchy/focal-point owner",
"future scene/group selection policies"
],
"recompute_when": [
"any compared massValue changes",
"input stage changes",
"calibrationDomainRef changes",
"measurementDomainRef changes",
"comparison set membership changes",
"equivalence tolerance changes",
"confidence policy changes"
],
"finality": "VISUAL_MASS_RELATIONS_ONLY"
}