COMPO · 23.03 · ANGULAR SPACING / SECTOR OCCUPANCY

Angle is geometry.
Occupancy is description.

23.03 переводит точные dx/dy от hub в polar angle, строит детерминированные cyclic gap descriptors и проверяет membership в явно заданных angular sectors. Пустой сектор, нулевой gap и неравномерный angular rhythm остаются наблюдениями, а не качественными вердиктами.

ModuleCompo 23.03
Angleexact atan2
Sectorsexplicit only
Occupancydescriptive
Metricsnone
NextSTOP

Angle and sector descriptors, no target fit

00 / contract
23.00 radial root
+ 23.01 exact hub
+ 23.02 radius observations with dx/dy

→ exact polar angle observations
→ cyclic angular spacing descriptors
→ explicit sector membership
→ sector occupancy descriptors

NO approximate tolerance
NO equal-spacing target
NO score
NO layout generator

Ownership is narrow

01 / owner
OWNS

Angle / spacing / sectors

Polar angles, cyclic gaps, explicit sector arcs, exact assignments and occupancy counts.

DEFERS

23.04 remains downstream

Approximation, target profiles, scoring, MetricResult and candidate generation remain outside this module.

Polar angle is derived from dx/dy

02 / angle
angleRadians = normalize(atan2(dy, dx)) ∈ [0, 2π)
angleDegrees = angleRadians × 180 / π

radius = 0 → direction undefined → N_A
angle  = 0 → valid eastward direction → OK

No angle is treated as semantic importance, hierarchy, mass or quality.

Cyclic spacing preserves exact geometry

03 / spacing
sort OK angular observations by angle (tie → subjectRef only for deterministic identity) for each adjacent pair around the circle: gap = nextAngle - currentAngle final gap wraps through 2π → 0 exact zero gap is valid sum(gaps) = 2π when ≥2 directions exist

Sectors are explicit arcs

04 / sectors
start < endordinary arc
start > endwrap-around arc crossing 0
start = endINVALID; full-circle intent is not inferred
boundariesstartInclusive / endInclusive are explicit

Membership keeps ambiguity

05 / assignment
ASSIGNED

Exactly one explicit sector contains the angle.

UNASSIGNED

No sector contains the angle; valid and non-judgmental.

AMBIGUOUS

Multiple sectors contain the angle → N_A, no winner.

N/A

Hub subject with radius=0 has no direction.

Occupancy is descriptive

06 / occupancy
occupancyCount    = count(ASSIGNED subjects in sector)
occupancyFraction = occupancyCount / applicableAngularSubjectCount

0 occupied subjects is valid numeric 0.
It does not imply a defect or low quality.

Exact upstream lineage is preserved

07 / lineage
Compo23.00 RadialSystemSeed ↓ exact Compo23.01 RadialHubDescriptor ↓ exact Compo23.02 RadialRadiusObservationSet ↓ exact Compo23.03 AngularObservationSet / SpacingSet / SectorSet root records remain immutable

Downstream boundary

08 / next owner
23.03Exact angles, cyclic gaps, explicit sectors and occupancy only.
23.04Approximation, target fit, scoring, bounded generator and final Topic23 tests.
Topic24Not started here.

Descriptor ≠ quality

09 / firewalls
equal spacing != automatically good unequal spacing != automatically bad empty sector != defect full sector != quality zero angular gap != zero score sector occupancy != visual mass angle != hierarchy orbital group != angular sector N_A != 0 INVALID != 0

CANON → LAB → DATA → IDEAS

10 / mandatory hooks
IDEAS_REFS[]Angular rhythm, radial emphasis, multi-sector systems.
DATA_CAPTURE[]Angles, gaps, assignments and occupancy lineage.
DEFERRED_SEMANTIC_INPUTS[]Approximation, style intent and target fit.
HUMAN_FEEDBACK_HOOKS[]Sector arc and membership corrections.
CONFLICT_PRIORITY_ASSUMPTIONS[]Source order/confidence never resolves overlap.
LAB_HOOKS[]Perceived spacing and sector-density studies.

23.03 regression suite

11 / deterministic tests

Tests cover exact root/hub/radius lineage, atan2 normalization, hub-direction N_A semantics, cyclic gaps, explicit wrap-around sectors, boundary inclusion, ambiguity preservation, occupancy zeros, immutable attachment and 23.04/Topic24 firewalls.

Tests not run yet.

DATA FOR LAYOUT ENGINE

12 / machine contract
{
  "module": "Compo 23.03",
  "name": "angular_spacing_sector_occupancy",
  "version": "1.0-canonical",
  "canonical_main_title": "Angular spacing / sector occupancy",
  "topic": "23_РАДИАЛЬНЫЙ_БАЛАНС_И_ЦЕНТРАЛЬНЫЕ_СИСТЕМЫ",
  "scope": "EXACT_COMPO23_00_ROOT_COMPO23_01_HUB_AND_COMPO23_02_RADIUS_LINEAGE_DERIVED_POLAR_ANGLES_EXPLICIT_ANGULAR_SECTORS_CYCLIC_GAP_DESCRIPTORS_AND_NONSCORING_SECTOR_OCCUPANCY_ONLY_WITHOUT_APPROXIMATION_TARGET_FIT_SCORING_OR_GENERATION",
  "main_topic_contract": {
    "topic_title": "Радиальный баланс и центральные системы",
    "topic_goal": "Формализует радиальные композиции: hub, rings, radius bands, angular sectors и распределение элементов вокруг центра.",
    "expected_output": "RadialGroupDescriptor, hub, rings, sectors",
    "planned_files": [
      "23.00 Radial system schema",
      "23.01 Hub/center detection",
      "23.02 Radius bands and orbital groups",
      "23.03 Angular spacing / sector occupancy",
      "23.04 Scoring, generator and tests"
    ]
  },
  "ownership": {
    "owner": "Compo23.03",
    "owns": [
      "RadialAngularObservation",
      "RadialAngularObservationSet",
      "RadialAngularSpacingDescriptor",
      "RadialAngularSpacingSet",
      "RadialAngularSectorDefinition",
      "RadialSectorMembershipClass taxonomy",
      "RadialSectorAssignment",
      "RadialSectorOccupancyDescriptor",
      "RadialAngularSectorSet",
      "RadialAngularSectorPolicy",
      "RadialAngularSectorAttachment",
      "exact atan2-derived polar angle normalization to [0, 2π)",
      "deterministic cyclic angular ordering and adjacent-gap derivation",
      "explicit angular-sector membership including wrap-around sectors",
      "sector occupancy counts/fractions as non-scoring descriptors",
      "identity/status/provenance rules for Topic23 angular layer",
      "non-mutating correction request for angular/sector lineage"
    ],
    "does_not_own": [
      "RadialSystemSchema / RadialSystemSeed identity — Compo23.00",
      "hub detection / hub truth — Compo23.01",
      "radius observations, radius bands, rings and orbital groups — Compo23.02",
      "raw point geometry or foreign position identities — upstream geometry owners",
      "approximate angle/radius tolerance, target fit, scoring, MetricResult or generator — Compo23.04",
      "symmetric balance / mirror correspondence — Topic21",
      "visual center of mass, moments and counterweights — Topic22",
      "hierarchy, dominance, semantic importance, beautyScore or final-layout ranking",
      "foreign geometry/style/semantic mutation"
    ]
  },
  "consumes": [
    "exact Compo23.00 root bundle",
    "exact Compo23.01 RadialHubDescriptor + RadialHubAttachment lineage",
    "exact Compo23.02 RadialRadiusObservationSet containing dx/dy/radius lineage",
    "optional explicit RadialAngularSectorDefinition[] and bounded policy"
  ],
  "provides": [
    "RadialAngularObservation[]",
    "RadialAngularObservationSet",
    "RadialAngularSpacingDescriptor[]",
    "RadialAngularSpacingSet",
    "RadialAngularSectorDefinition[]",
    "RadialSectorAssignment[]",
    "RadialSectorOccupancyDescriptor[]",
    "RadialAngularSectorSet",
    "RadialAngularSectorAttachment"
  ],
  "owns_metrics": [],
  "independent_numeric_votes": 0,
  "status_semantics": {
    "OK": "valid exact local angular/sector descriptor",
    "N_A": "missing/conflicting/ambiguous/not-applicable evidence; never numeric zero",
    "INVALID": "malformed or impossible record; never numeric zero"
  },
  "angle_rules": [
    "angleRadians = normalize(atan2(dy, dx)) into [0, 2π)",
    "angleDegrees = angleRadians × 180 / π",
    "radius=0 makes direction undefined -> N_A; angle is not coerced to zero",
    "east=0, north=π/2, west=π, south=3π/2 in the bound coordinate frame",
    "no orientation desirability is inferred"
  ],
  "spacing_rules": [
    "only OK angular observations participate in cyclic order",
    "order is angle ascending with subjectRef lexical tie-break used only for deterministic identity",
    "adjacent cyclic gaps are in [0, 2π] and exact zero is valid for coincident rays",
    "with at least two applicable observations, cyclic gaps sum to 2π within floating arithmetic tolerance",
    "gap size is a descriptor, not rhythm quality or target fit"
  ],
  "sector_policy": {
    "definitionMode": "EXPLICIT_ARCS_ONLY",
    "membershipMode": "EXACT_ANGLE_ONLY",
    "multipleMatchMode": "N_A_NO_GUESS",
    "gapMode": "UNASSIGNED_OK",
    "maxAngularObservations": [
      1,
      4096
    ],
    "maxSectors": [
      0,
      512
    ],
    "maxSpacingDescriptors": [
      0,
      4096
    ],
    "overflow": "N_A_WITHOUT_TRUNCATION",
    "autoSectorDiscovery": false,
    "autoTolerance": false,
    "autoEqualSpacingTarget": false,
    "autoScoring": false
  },
  "sector_rules": [
    "sector start/end angles must each be in [0,2π)",
    "start < end defines a non-wrapping arc; start > end defines a wrap-around arc crossing 0",
    "start == end is INVALID because full-circle intent must not be inferred",
    "boundary inclusion is explicit per endpoint",
    "zero occupied subjects is valid occupancyCount=0",
    "overlapping explicit sectors may make one subject AMBIGUOUS -> N_A; no source/confidence winner",
    "uncovered angle -> UNASSIGNED with OK status; not a quality failure"
  ],
  "root_attachment_contract": {
    "radialSystemSeedRef": "exact Compo23.00 seed lineage",
    "hubDescriptorRef": "exact Compo23.01 descriptor identity",
    "radiusObservationSetRef": "exact Compo23.02 radius set identity",
    "angularObservationSetRef": "exact Compo23.03 angular set identity",
    "angularSpacingSetRef": "exact Compo23.03 spacing set identity",
    "angularSectorSetRef": "exact Compo23.03 sector set identity",
    "rootMutation": false,
    "metricResultRefs": []
  },
  "firewalls": [
    "angle != radius",
    "angle != hierarchy or semantic importance",
    "angle=0 is valid east direction, not N_A",
    "radius=0 direction is N_A, not angle 0",
    "coincident rays may have exact zero angular gap",
    "zero gap != zero score",
    "equal angular spacing != automatically good",
    "unequal angular spacing != automatically bad",
    "sector occupancy count != visual mass",
    "empty sector != defect",
    "full sector != quality",
    "angular sector != orbital group",
    "angular sector != symmetry class",
    "wrap-around sector != approximation",
    "multiple sector match -> N_A, not winner selection",
    "descriptor != score",
    "N_A != 0",
    "INVALID != 0",
    "heuristic != law",
    "local != global",
    "geometry != interpretation",
    "correction request != foreign mutation"
  ],
  "topic23ProgressAfterThisModule": "4/5 local",
  "next_module": "Compo 23.04 — Scoring, generator and tests",
  "hard_stop": "No 23.04 implementation in this file"
}
VISITS / ...