LOTS_BACKEND_STANDARD - TheDaniel166/moira GitHub Wiki
Moira Lots Backend Standard
Governing Principle
The Moira lots backend is a sovereign computational subsystem. Its definitions, layer boundaries, terminology, invariants, failure doctrine, and determinism rules are stated here and are frozen until explicitly superseded by a revision to this document.
This document reflects current implementation truth as of Lots Phase 11. It
describes the subsystem that actually exists in moira/lots.py; it does not
describe aspirational future capabilities.
Part I - Architecture Standard
1. Authoritative Computational Definitions
1.1 Core lot computation
An Arabic Part in Moira is:
The authoritative result of
ArabicPartsService.calculate_parts, computed from the doctrinal formulaAsc + Add - Subtract (mod 360)after reference resolution and day/night reversal where the catalogue definition requires it.
The computational core remains the authority for:
- lot longitude
- effective formula operands
- day/night reversal behavior
- reference resolution
- lot admission or omission under the current policy
Later layers may preserve, classify, inspect, aggregate, or network this truth. They may not recompute lot doctrine independently.
1.2 Part definition
A part definition in Moira is:
One immutable doctrinal catalogue entry represented by
PartDefinition, declaring the lot name, day operands, reversal rule, category string, and optional description.
PARTS_DEFINITIONS is the authoritative lot catalogue.
1.3 Computation truth
An Arabic part computation truth in Moira is:
The preserved doctrinal and computational path that records which operand keys were requested, which keys actually resolved, whether reversal applied, and which structured references were used for the returned longitude.
This truth is carried by ArabicPart.computation_truth. It is descriptive
only. It does not change the formula or result.
1.4 Dependency
A lot dependency in Moira is:
One formal operand relation derived from preserved computation truth, expressing whether a lot depends on a given add or subtract operand and how that operand was resolved.
The dependency layer distinguishes:
| Term | Definition |
|---|---|
all_dependencies |
all doctrinal operand dependencies preserved on the lot |
dependencies |
the currently admitted dependency subset |
inter_lot_dependencies |
admitted dependencies whose reference kind is DERIVED_LOT |
external_dependencies |
admitted dependencies whose reference kind is EXTERNAL |
Under the current default policy, dependencies == all_dependencies.
1.5 Lot condition profile
A lot condition profile in Moira is:
A backend-only integrated structural summary derived from one
ArabicPart, combining lot category, reversal state, and dependency composition into a single per-lot condition vessel.
LotConditionProfile is derived only from lower-layer truth. It is not a
second lot engine.
1.6 Chart condition profile
A lot chart condition profile in Moira is:
A deterministic chart-wide aggregation of per-lot condition profiles, reporting structural counts, dependency totals, and strongest / weakest lots under the currently embodied ranking.
1.7 Lot condition network profile
A lot condition network profile in Moira is:
A deterministic directed graph projection over admitted inter-lot dependency truth and the existing per-lot condition profiles.
It includes at least:
- one node per computed lot profile
- one directed edge per admitted inter-lot dependency
- unilateral vs reciprocal edge visibility
- incoming / outgoing / reciprocal counts per node
- isolated lots
- direct-degree connectivity summaries
This is a structural backend layer only. It is not an interpretive network.
2. Layer Structure
The backend is organised into one computational core plus ten formalised post-core layers. Each layer consumes outputs already produced below it. No layer reaches upward.
Core - Authoritative lot computation (`calculate_parts`)
Phase 1 - Truth preservation
Phase 2 - Classification
Phase 3 - Inspectability and vessel hardening
Phase 4 - Doctrine / policy surface
Phase 5 - Dependency formalisation
Phase 6 - Dependency inspectability / hardening
Phase 7 - Integrated per-lot condition
Phase 8 - Chart-wide condition intelligence
Phase 9 - Dependency / condition network intelligence
Phase 10 - Full-subsystem hardening
Phase 11 - Architecture freeze / validation codex
Layer boundary rules
A layer above the core:
- may consume preserved truth from lower layers
- may classify or aggregate earlier truth
- may add invariant checks that reject internally inconsistent vessels
- may not recompute lot doctrine independently
- may not alter legacy lot longitude or formula semantics by reclassification
- may not mutate an earlier-layer vessel in place
- may not introduce interpretation, recommendation, or UI concerns
3. Delegated Assumptions
The lots backend delegates to external modules without redefining them:
| Concern | Delegated to | Convention |
|---|---|---|
| zodiac sign ordering | moira.constants.SIGNS |
ordered list of 12 sign names |
| sign derivation | moira.constants.sign_of |
returns sign name, glyph, and in-sign degree |
| chart access | moira.chart.ChartContext |
exposes planet longitudes, nodes, houses, and day-chart state |
Changes to those delegated sources propagate into the lots subsystem. This document does not freeze their independent doctrine.
4. Doctrine Surface
4.1 Catalogue doctrine
Lot doctrine begins with PARTS_DEFINITIONS. Each lot’s:
day_addday_subreverse_at_nightcategory
is authoritative unless the catalogue itself is revised.
4.2 Reference doctrine
The current engine supports the following reference classes where resolvable:
- direct planets and chart nodes
- angles (
Asc,Dsc,MC,IC) - house cusps (
H1...H12) - house rulers (
Ruler H1...Ruler H12) - angle-ruler aliases
- planet-sign rulers (
Ruler Sun, etc.) - fixed-degree constants
- optional externals (
Syzygy, prenatal lunations,Lord of Hour) - derived lots currently embodied in the engine:
FortuneSpiritEros (Valens)
No additional reference doctrine is implied by this document.
4.3 Reversal doctrine
Day/night reversal doctrine is embodied directly by each PartDefinition’s
reverse_at_night field. Reversal applies only when:
reverse_at_nightisTrue- the chart is not a day chart
4.4 Policy doctrine
LotsComputationPolicy makes current doctrine explicit without changing the
default result.
| Policy area | Type | Current default |
|---|---|---|
| unresolved reference handling | LotsReferenceFailureMode |
SKIP |
| derived-lot admissibility | LotsDerivedReferencePolicy |
all supported derived lots enabled |
| external-reference admissibility | LotsExternalReferencePolicy |
all supported external references enabled |
The normative default is:
LotsComputationPolicy()must preserve the current historical subsystem behavior exactly.
5. Classification
ArabicPartClassification is descriptive only. It classifies:
- deterministic category tags
- deterministic primary category
- reversal state
- add-reference kind
- sub-reference kind
Classification describes preserved truth. It does not affect lot longitude, formula semantics, or admission logic.
6. Inspectability
ArabicPart exposes derived inspectability helpers so callers do not need to
reconstruct structure from nested truth:
category_tagsprimary_categoryreversal_kindis_reversedadd_reference_kindsub_reference_kinddependency_countall_dependency_countinter_lot_dependenciesexternal_dependenciescondition_state
The chart and network layers also expose small derived inspectability helpers:
LotChartConditionProfile.profile_countLotChartConditionProfile.strongest_countLotChartConditionProfile.weakest_countLotConditionNetworkNode.degree_countLotConditionNetworkNode.is_isolatedLotConditionNetworkProfile.node_countLotConditionNetworkProfile.edge_count
These properties are derived only. They do not change doctrine.
7. Failure Doctrine
7.1 Input failure behavior
Malformed raw inputs must fail clearly and deterministically before lot computation proceeds.
Current explicit failures include:
- duplicate normalized planet names
- empty normalized planet names
- non-finite planet longitudes
- house cusp lists not containing exactly 12 entries
- non-integer house cusp numbers
- house cusp numbers outside
1..12 - missing house cusp numbers
- non-finite house cusp values
- unsupported policy enum values
- malformed nested policy objects
- non-boolean nested policy flags
7.2 Unresolved reference behavior
Unresolved doctrinal references are governed by policy:
| Mode | Behavior |
|---|---|
SKIP |
omit the lot silently from the returned result set |
RAISE |
raise ValueError("Unresolved lot ingredient reference: ...") |
This doctrine applies only after input validation and policy validation have already succeeded.
7.3 Internal inconsistency behavior
If a vessel is constructed with internally inconsistent truth, classification,
dependency, chart, or network state, it must fail loudly with ValueError.
Silent internal drift is prohibited.
8. Determinism Guarantees
For identical validated inputs and policy, the subsystem guarantees:
- deterministic lot inclusion / omission
- deterministic lot ordering
- deterministic category parsing
- deterministic dependency ordering
- deterministic condition-profile ordering
- deterministic chart strongest / weakest sets
- deterministic network node ordering
- deterministic network edge ordering
- deterministic isolated / most-connected summaries
No public result vessel may depend on hash order or incidental iteration order.
Part II - Invariant Register
9. Vessel Invariants
The following invariants are normative.
9.1 ArabicPartComputationTruth
formulamust match the effective operand keysreversed_for_chartrequiresreversed_at_nightadd_reference.keymust matcheffective_add_keysub_reference.keymust matcheffective_sub_key
9.2 ArabicPartClassification
category_tagsmust not be emptyprimary_categorymust be contained incategory_tags
9.3 LotDependency
- each dependency must have a non-empty
effective_key source_partandtarget_partare not permitted to collapse into a self-edge later in the network layer
9.4 LotConditionProfile
primary_categorymust be contained incategory_tagsdependenciesmust be a subset ofall_dependencies- direct / indirect / inter-lot / external counts must match
dependencies statemust match the derived dependency polarity
9.5 ArabicPart
longitudemust be in[0, 360)formulamust matchcomputation_truth.formulawhen truth is present- classification must agree with category ordering and reversal truth
- dependencies must agree with preserved computation truth
dependenciesmust be a subset ofall_dependenciescondition_profilemust agree with lot classification and dependencies
9.6 LotChartConditionProfile
- state counts must match profile states
- dependency totals must match profile totals
profilesmust be in deterministic orderstrongest_partsmust match the derived strongest rankingweakest_partsmust match the derived weakest ranking
9.7 LotConditionNetworkNode
reciprocal_countmay not exceed either incoming or outgoing count
9.8 LotConditionNetworkEdge
source_partandtarget_partmust differ
9.9 LotConditionNetworkProfile
- nodes must be in deterministic order
- edges must be in deterministic order
- reciprocal and unilateral edge counts must match the edges
- reciprocal edges must have reverse partners
- unilateral edges must not have reverse partners
- node incoming / outgoing / reciprocal counts must match the edges
isolated_partsmust match the nodesmost_connected_partsmust match node degree counts
Part III - Public Surface and Validation Codex
10. Stable Public Surface
The stable lots backend surface is the combination of:
- result vessels:
PartDefinitionArabicPartLotReferenceTruthArabicPartComputationTruthLotReferenceClassificationArabicPartClassificationLotDependencyLotConditionProfileLotChartConditionProfileLotConditionNetworkNodeLotConditionNetworkEdgeLotConditionNetworkProfile
- enums:
LotReferenceKindLotReversalKindLotDependencyRoleLotConditionStateLotConditionNetworkEdgeModeLotsReferenceFailureMode
- policy types:
LotsDerivedReferencePolicyLotsExternalReferencePolicyLotsComputationPolicy
- service:
ArabicPartsService
- module entrypoints:
calculate_lotscalculate_lot_dependenciescalculate_all_lot_dependenciescalculate_lot_condition_profilescalculate_lot_chart_condition_profilecalculate_lot_condition_network_profilelist_parts
Internal helpers remain implementation detail unless explicitly exported later.
11. Minimum Validation Codex
Any substantive change to moira/lots.py must, at minimum, preserve:
- lot formula and longitude semantics
- structured truth consistency
- classification consistency
- dependency consistency
- condition-profile consistency
- chart-profile consistency
- network consistency
- deterministic failure behavior
Minimum validation commands:
.\.venv\Scripts\python.exe -m pytest tests\unit\test_dignities_and_lots.py -q
.\.venv\Scripts\python.exe -m pytest tests\unit\test_rule_engine_validation.py -q -k lots
.\.venv\Scripts\python.exe -m py_compile moira\lots.py tests\unit\test_dignities_and_lots.py
If the public package surface changes later, the matching API-freeze test must also be included in the minimum validation set.
12. Non-Goals Frozen By This Standard
The current lots backend does not include:
- interpretive meanings for lots
- recommendation or judgment logic
- chart-wide interpretive synthesis
- UI or rendering concerns
- probabilistic confidence scoring
- external doctrine beyond the currently embodied reference set
Those concerns belong to later layers or different subsystems. They are not part of the current constitutional backend.