Timing & Timelords
Firdaria, decennials, Zodiacal Releasing, time-boundary ownership, and immutable timelord result contracts.
Timelords Backend Standard
Subsystem: moira/profections.py, moira/timelords.py
Computational Domains: Profections, Firdaria, Decennials, Zodiacal Releasing
Constitutional Phase: 11 — Architecture Freeze and Validation Codex
Status: Constitutional
Closed Decennial boundary — 2026-07-27. The complete admitted Decennials contract is L1/L2. Levels 3–4 and named deep-subdivision methods are closed exclusions, not unfinished engine work. The runtime and REST request surface ends at L2. Zodiacal Releasing classifies all twelve places from Fortune, identifies only angular places as peaks, and rejects queries at or beyond the exact full-circuit endpoint.
Phase-2 time-basis correction — 2026-07-25. Decennials now preserves a machine-readable dual-basis receipt. Its periods are measured on the Valens 360-day distribution coordinate, while
start_jd/end_jdare explicitly identified as elapsed-Julian-day projections from the natal instant. Annual profection schedule ages are civil-anniversary ages. Zodiacal Releasing profile requests must ask for a level that was generated.
Phase-2 ZR source lock — 2026-07-25. Valens IV.4 now owns the Spirit/Fortune same-sign start shift and the exact 211-month Loosing-of-the-Bond boundary. These rules are covered by a source-locked fixture; the inconsistent intervening numerical table is not treated as an oracle against the source prose.
Dated monthly profection contract — 2026-07-27. The admitted twelve-sign monthly sequence now has an explicit dated projection. Moira partitions the exact elapsed duration between consecutive civil anniversaries into twelve equal-microsecond, half-open intervals in an explicit IANA timezone. The receipt identifies this as a computational projection, not as Valens IV.28's separate luminary-distance method.
Part I — Architecture Standard
§1. Computational Definitions
§1.0 Annual and Monthly Profections
annual_profection() advances the natal Ascendant by one whole sign for each
completed year. monthly_profection() advances the resulting longitude by
one whole sign for each month index in 0..11.
profection_schedule() owns civil-anniversary age resolution and attaches a
query-specific ProfectionChronology. REST callers normalized to UTC supply
civil_timezone; explicit IANA zones resolve through the standard-library
zoneinfo interface. The request fails closed if the host lacks the requested
IANA entry, and the result does not claim an unavailable database version.
The sole admitted dated interval policy is
equal_twelfths_of_civil_anniversary_year. It divides elapsed UTC time between
the exact local civil anniversary and the following anniversary into twelve
integer-microsecond partitions. Boundaries are start-inclusive and
end-exclusive. No fixed 30-day, 365.25-day, or civil-calendar-month
approximation is admitted.
The chronology method is classified as computational_projection. Valens
IV.28's day-Sun/night-Moon distance method is a distinct technique outside
this contract; the equal-twelfths policy does not claim historical
equivalence.
Authoritative doctrine and boundary details:
wiki/01_doctrines/timelords/monthly_profection_chronology_doctrine.md.
§1.1 Firdaria
Firdaria is a Persian/Medieval time-lord technique assigning rulership of life-periods to the seven classical planets and the lunar nodes in a fixed Chaldean-order sequence. It is exposed and validated separately, but it is not part of Moira's admitted Hellenistic profile. The complete cycle spans 75 years.
The authoritative engine is firdaria(natal_jd, is_day_chart). It accepts a Julian
Day number and a sect indicator and returns a list of FirdarPeriod records covering
the full 75-year cycle from birth. Each record preserves the planet, level, major
planet, start and end Julian Day, duration in years, and the sequence kind that
generated it.
Sequence kinds (FirdarSequenceKind):
| Value | Meaning |
|---|---|
DIURNAL | Day chart: Sun-led sequence |
NOCTURNAL_STANDARD | Night chart: Moon-led, traditional ordering |
NOCTURNAL_BONATTI | Night chart: Moon-led, Bonatti variant ordering |
The sequence_kind field is set only on major-period (level=1) records. Sub-period
records do not repeat it; they inherit structural context through their major_planet
field.
The nocturnal variant (standard vs. Bonatti) is a doctrinal choice expressed at call
time. The default is NOCTURNAL_STANDARD. Both variants share the same computational
structure; only the planet ordering changes.
§1.2 Decennials
Decennials is a Hellenistic planetary time-lord technique assigning major life periods to the sect light and then proceeding through the seven classical planets in zodiacal order from that luminary. The admitted Moira doctrine uses 129-month major periods, 30-day schematic months, and a 360-day distribution year. The complete major cycle spans 903 schematic months, or 75 years 3 months in distribution notation.
The authoritative engine is decennials(natal_jd, natal_positions, is_day_chart).
It accepts a natal Julian Day, the seven classical longitudes, and a sect
indicator and returns a flat list of DecennialPeriod records covering the
complete admitted sequence. Each record preserves level, planet, sequence
truth, major lineage, parent lineage, duration, sequence kind, and the full
time-basis receipt.
Valens distinguishes the 365¼-day universal/lived year from the 360-day distribution year. Moira therefore does not describe a 129-month major as 129 civil-calendar months. The engine:
- counts the target instant by elapsed lived days from
natal_jd; - locates that elapsed-day coordinate within the 360-day distribution sequence; and
- exposes the resulting civil JD/date only as a projection of the symbolic boundary from the natal instant.
The following fields make that distinction inspectable:
| Surface | Value / meaning |
|---|---|
DecennialTimeBasis.VALENS_LIVED_DAYS_TO_360_DAY_DISTRIBUTION | Frozen distribution-time doctrine token |
DecennialTimeBasis.ELAPSED_JULIAN_DAYS_FROM_NATAL_JD | Frozen calendar-projection token |
sequence_origin_jd | Natal JD from which elapsed lived days are counted |
start_distribution_day, end_distribution_day | Half-open elapsed-day bounds in distribution space |
distribution_years | Period duration divided by 360 |
start_jd, end_jd | Calendar projections, not claims of civil-month anniversaries |
Sequence kinds (DecennialSequenceKind):
| Value | Meaning |
|---|---|
DIURNAL_SOLAR | Day chart: Sun-led sequence |
NOCTURNAL_LUNAR | Night chart: Moon-led sequence |
Sequence assembly truth: decennial_sequence_truth() evaluates the
Classic 7 dependencies before any period is generated. Its
DecennialSequenceAssemblyTruth preserves chart sect, sect light, sequence
kind, normalized sect-light longitude, one DecennialSequenceBodyTruth per
classical planet, the final sequence when evaluable, and any ambiguous
non-sect-light groups.
The sect light is always the first lord. One non-sect-light planet may share
its longitude because the starting-lord rule resolves that ordering. Two or
more non-sect-light planets at the same longitude are not ordered by a private
planet list: the assembly is typed not_evaluable with
reason="non_sect_longitude_tie", and decennials() fails closed. Every
generated L1/L2 period carries the same evaluated assembly receipt.
Admitted levels and deep doctrine:
| Doctrine | Admitted levels |
|---|---|
| Shared Decennials core | L1 + L2 |
deep_subdivision_method="valens" | Not admitted |
deep_subdivision_method="hephaistio" | Not admitted |
Any request for L3/L4 or either named deep method fails closed. This is the finished contract boundary. A future proposal would be a separate source-admission project, not completion work for this engine release.
§1.4 Valens Distributions (Closed Interpretive Exclusion)
The Valens distributions/transmissions delineation layer is not admitted. The earlier implementation did not preserve the receiver relation needed to select a source item, duplicated incomplete tables, attached effects automatically, and inferred benefic/malefic scores from English keywords. Those behaviours are not source-owned doctrine and have been removed.
This exclusion is separate from the Decennial L1/L2 depth boundary.
Neither DecennialPolicy.deep_subdivision_method="valens" nor
"hephaistio" is selectable in the admitted runtime. Neither exclusion
enables delineations, effects, polarities, or dignity scores.
The interpretive layer has no public export, period/profile field, automatic attachment, REST option, score, aggregate, or dignity bridge. It is not a missing part of the admitted Hellenistic profile. Any future proposal would require its own item-complete source transcription, explicit distributor and receiver semantics, typed unscored result design, and source-owned fixtures. Generic good/bad labels and numerical scores remain outside the admitted design.
The internal arithmetic is doctrinal rather than astronomical:
- major periods are fixed at
129months - the month basis is fixed at
30days L2rotates the minor-month allotments from each major lord- no L3/L4 recursion is admitted
§1.3 Zodiacal Releasing
Zodiacal Releasing is a Hellenistic predictive technique that releases from a natal
Lot (Spirit or Fortune) through the twelve signs of the zodiac. Periods are assigned
by sign in sequence, with duration determined by the sign's MINOR_YEARS value.
The technique recurses through four levels of releasing simultaneously.
The authoritative engine is zodiacal_releasing(lot_longitude, natal_jd). It accepts
a Lot's ecliptic longitude and a Julian Day number and returns a list of
ReleasingPeriod records. Each record preserves the releasing sign, its ruler, the
level of releasing, the lot name, duration in years, the Loosing of the Bond flag,
the angularity from Fortune, and the year-basis.
MINOR_YEARS: The canonical sign-to-duration mapping is an immutable constant in the module. It assigns years-per-sign based on planetary minor years under the Hellenistic system. This mapping is the foundational arithmetic of the technique and is not configurable at call time.
Valens IV.4 start shift: When Spirit and Fortune occupy the same sign and releasing is requested from Spirit, bodily matters remain with that sign while the activity sequence begins from the following sign. The engine therefore advances the starting sign by one only for this explicitly supplied Spirit/Fortune same-sign case.
Loosing of the Bond: Valens' complete circuit is 17 years 7 months, or 211
symbolic months. After a complete twelve-sign subcycle that began in a sign
whose allotment exceeds that circuit, the admitted generator transfers the
next period to the opposite sign and marks that receiving period as a Loosing
of the Bond.
ReleasingPeriod.is_loosing_of_bond preserves this generative event; it is not
inferred from an upper/lower-level sign match after the fact.
The source-locked Gemini fixture is exact: inside a 20-year Gemini major, Level 2 reaches its 211-month circuit boundary, transfers to Sagittarius for 12 months, and then uses the final 17 months in Capricorn. The prose and explanatory note govern this fixture; the internally inconsistent numerical table on the intervening annotated-PDF page is not used.
Angularity from Fortune: Each sign's relationship to the natal Lot of Fortune
determines its angularity class. Angular signs (1, 4, 7, 10 from Fortune) carry the
ANGULAR classification; the following signs carry SUCCEDENT; the remaining carry
CADENT. This classification is preserved as an integer (1-based distance) and a
typed ZRAngularityClass on each period.
When Fortune is supplied, every period receives an evaluated
ZRFortuneAngularityTruth with one of the twelve integer places, one of the
three classes, and a peak boolean that is true only for the four angular
places. When Fortune is omitted, the raw receipt is typed not_evaluable with
reason="fortune_not_supplied"; its Fortune sign, place, class, and peak truth
are all None. The legacy ReleasingPeriod.is_peak_period field remains
False as a compatibility projection, so callers must use
fortune_angularity_truth when they need to distinguish unevaluated from an
evaluated non-peak period.
ZRAngularityClass Value | Meaning |
|---|---|
ANGULAR | 1st, 4th, 7th, or 10th sign from Fortune |
SUCCEDENT | 2nd, 5th, 8th, or 11th sign from Fortune |
CADENT | 3rd, 6th, 9th, or 12th sign from Fortune |
Levels: Four levels of releasing are computed simultaneously. Level 1 is the
outermost (slowest), Level 4 is the innermost (fastest). All four are returned in a
single flat list discriminated by the level field.
zr_sequence_profile(periods, level) rejects an empty period list and rejects
any requested level absent from the supplied periods. The REST
profile_level must therefore be less than or equal to the request's generated
levels; an impossible profile request is never serialized as an empty,
apparently valid aggregate.
Full-circuit boundary: The twelve MINOR_YEARS values sum to 211 symbolic
years. current_releasing() accepts instants inside that half-open interval
and rejects an instant exactly at, or later than, its endpoint.
Source receipt: tests/golden/hellenistic_zr_valens_iv4.json, backed by
Valens, Anthologies IV.4 (Riley annotated PDF pp. 329, 331, and 333).
§2. Layer Structure
The timelords subsystem is organized into ten layers, each building on the prior according to the constitutional dependency graph.
| Layer | Phase | Firdaria | Decennials | Zodiacal Releasing |
|---|---|---|---|
| 0 | Core | firdaria() | decennials() | zodiacal_releasing() |
| 1 | Truth Preservation | FirdarPeriod | DecennialPeriod | ReleasingPeriod |
| 2 | Classification | FirdarSequenceKind | DecennialSequenceKind | ZRAngularityClass |
| 3 | Inspectability | is_active_at(), duration properties | lineage helpers, is_active_at(), duration properties | is_active_at(), duration properties |
| 4 | Policy | sequence_kind parameter | DecennialPolicy (deep method fixed to None) | lot_name, use_loosing_of_bond |
| 5 | Relational Formalization | FirdarMajorGroup, group_firdaria() | DecennialMajorGroup, DecennialPeriodGroup, group_decennials() | ZRPeriodGroup, group_releasing() |
| 6 | Relational Hardening | subset properties, chronological guard | recursive containment and chronology guards | containment guard, is_leaf, all_periods_flat() |
| 7 | Integrated Local Condition | FirdarConditionProfile, firdar_condition_profile() | DecennialConditionProfile, decennial_condition_profile() | ZRConditionProfile, zr_condition_profile() |
| 8 | Aggregate Intelligence | FirdarSequenceProfile, firdar_sequence_profile() | DecennialSequenceProfile, decennial_sequence_profile() | ZRSequenceProfile, zr_sequence_profile() |
| 9 | Network Intelligence | FirdarActivePair, firdar_active_pair() | DecennialActivePair, DecennialActivePath, decennial_active_pair(), decennial_active_path() | ZRLevelPair, zr_level_pair() |
| 10 | Hardening | validate_firdaria_output() | validate_decennials_output() | validate_releasing_output() |
Valens Distributions: closed exclusion under §1.4. They are not an additional layer on the admitted Decennials or Zodiacal Releasing architecture, and they are not release backlog.
§3. Delegated Assumptions
The timelords subsystem does not compute the following. Callers are responsible for supplying correct values.
For Firdaria:
natal_jd: a valid Julian Day number representing the moment of birthis_day_chart: the sect determination (diurnal or nocturnal), computed externally from the chart's sun/ascendant relationship- nocturnal variant selection: the caller's choice of
NOCTURNAL_STANDARDvs.NOCTURNAL_BONATTIis not validated against any external authority
For Zodiacal Releasing:
lot_longitude: the ecliptic longitude of the Lot, computed externally via the Lot formula (typicallyAsc + Fortune/Spirit − Sun/Moon)natal_jd: a valid Julian Day number representing the moment of birth- the Lot used (Spirit vs. Fortune vs. other) is identified only by the
lot_namestring passed at call time; the subsystem does not verify it
For Decennials:
natal_jd: a valid Julian Day number representing the moment of birthnatal_positions: the tropical longitudes of the seven classical planets, supplied externally and keyed by canonical planet nameis_day_chart: the sect determination (diurnal or nocturnal), computed externally- deep-method selection: the caller's choice of
None,valens, orhephaistiois validated for internal admissibility only; the subsystem does not infer it from source preference or chart context
§4. Doctrine Surface
The doctrinal choices made by the timelords subsystem are explicit and located.
Profection doctrine and projection policy:
| Choice | Location | Default |
|---|---|---|
| Completed-age basis | profection_schedule() | exact civil anniversary |
| Explicit transport timezone | civil_timezone | caller's natal_dt.tzinfo compatibility path |
| Monthly interval projection | MonthlyProfectionIntervalPolicy | equal_twelfths_of_civil_anniversary_year |
| Repeated local anniversary | ProfectionAmbiguousTimePolicy | explicit earlier_occurrence or later_occurrence; no guessed fold |
| Boundary membership | ProfectionIntervalBoundarySemantics | start_inclusive_end_exclusive |
| Method classification | ProfectionChronologyMethod | computational_projection |
| February 29 anniversary | LeapDayAnniversaryPolicy | explicit selection required |
Firdaria doctrine:
| Choice | Location | Default |
|---|---|---|
| Nocturnal ordering variant | firdaria() parameter sequence_kind | NOCTURNAL_STANDARD |
| Sub-period major identification | FirdarPeriod.major_planet field | always set |
| Node treatment | _FIRDARIA_NODES constant | ['North Node', 'South Node'] |
| Luminary classification | _FIRDARIA_LUMINARIES constant | ['Sun', 'Moon'] |
Zodiacal Releasing doctrine:
| Choice | Location | Default |
|---|---|---|
| Minor years mapping | MINOR_YEARS module constant | Hellenistic standard |
| Loosing of the Bond | ReleasingPeriod.is_loosing_of_bond field | computed at engine time |
| Angularity from Fortune | ReleasingPeriod.angularity_from_fortune field | computed at engine time |
use_loosing_of_bond flag | ReleasingPeriod.use_loosing_of_bond field | always preserved |
Decennials doctrine:
| Choice | Location | Default |
|---|---|---|
| Starting lord basis | DecennialPolicy.start_lord_basis | sect_light |
| Sequence mode | DecennialPolicy.sequence_mode | zodiacal_from_sect_light |
L2 subdivision mode | DecennialPolicy.subperiod_mode | rotated_minor_months |
| Major period length | DecennialPolicy.major_months | 129 |
| Month basis | DecennialPolicy.month_basis_days | 30 |
| Deep method | DecennialPolicy.deep_subdivision_method | None; all non-None values rejected |
§5. Public Vessels
The following are the constitutional public vessels of the timelords subsystem.
Enumerations:
MonthlyProfectionIntervalPolicy— identifies the admitted dated monthly projectionProfectionAmbiguousTimePolicy— explicitly resolves a repeated local anniversary when one occursProfectionChronologyMethod— distinguishes computational projection from historical-method claimsProfectionIntervalBoundarySemantics— freezes half-open membershipFirdarSequenceKind— discriminates the Firdaria sequence variantTimelordEvaluationStatus— discriminates evaluated from not-evaluable atomic timelord truthDecennialSequenceKind— discriminates the Decennials sequence variantDecennialTimeBasis— names the admitted distribution and projection basesZRAngularityClass— discriminates the angularity of a releasing period from Fortune
Atomic truth vessels:
DecennialSequenceBodyTruth— one classical planet's normalized longitude and forward arc from the sect lightDecennialSequenceAssemblyTruth— complete sect-light dependency, ordering, ambiguity, and final-sequence receiptZRFortuneAngularityTruth— Fortune dependency, place, class, and raw peak truth for one releasing sign
Truth-preservation vessels:
MonthlyProfectionInterval— one dated sign/lord step with exact UTC and Julian boundariesProfectionChronology— annual anchors, timezone provenance, query, active month, and the complete twelve-interval receiptFirdarPeriod— a single Firdaria period at any levelDecennialPeriod— a single Decennials period at any admitted levelReleasingPeriod— a single Zodiacal Releasing period at any level
Relational vessels:
FirdarMajorGroup— a major Firdaria period with its associated sub-periodsDecennialMajorGroup— a major Decennials period with its immediate subordinate periodsDecennialPeriodGroup— a recursive Decennials subordinate-period groupingZRPeriodGroup— a releasing period at any level with its nested sub-groups
Condition vessels:
FirdarConditionProfile— integrated doctrinal summary for oneFirdarPeriodDecennialConditionProfile— integrated doctrinal summary for oneDecennialPeriodZRConditionProfile— integrated doctrinal summary for oneReleasingPeriod
Aggregate vessels:
FirdarSequenceProfile— chart-wide summary of a full Firdaria sequenceDecennialSequenceProfile— chart-wide summary of a full Decennials sequenceZRSequenceProfile— sequence-wide summary of releasing periods at a given level
Network vessels:
FirdarActivePair— the major/sub lord pair active at a point in timeDecennialActivePair— the major/sub pair active at a point in timeDecennialActivePath— the full active Decennials lineage at a point in timeZRLevelPair— structural edge between two adjacent releasing levels
Computational functions:
profection_chronology(...)— typed dated monthly projection for one queryprofection_schedule(...)— current annual profection plus its chronologyfirdaria(natal_jd, is_day_chart, ...)— core Firdaria enginedecennial_sequence_truth(natal_positions, is_day_chart)— typed sect-light sequence-assembly receiptdecennials(natal_jd, natal_positions, is_day_chart, ...)— core Decennials enginezr_fortune_angularity_truth(period_sign, fortune_sign)— typed Fortune dependency and angular-place receiptzodiacal_releasing(lot_longitude, natal_jd, ...)— core Zodiacal Releasing enginegroup_firdaria(periods)— relational grouping for Firdariagroup_decennials(periods)— relational grouping for Decennialsgroup_releasing(periods)— relational grouping for Zodiacal Releasingfirdar_condition_profile(period)— condition profile for a Firdaria perioddecennial_condition_profile(period)— condition profile for a Decennials periodzr_condition_profile(period)— condition profile for a Releasing periodfirdar_sequence_profile(periods)— aggregate profile for a Firdaria sequencedecennial_sequence_profile(periods)— aggregate profile for a Decennials sequencezr_sequence_profile(periods, level)— aggregate profile for a Releasing sequencefirdar_active_pair(periods, jd)— network node active at a Julian Daydecennial_active_pair(periods, jd)— Decennials major/sub pair active at a Julian Daydecennial_active_path(periods, jd)— full Decennials lineage active at a Julian Dayzr_level_pair(upper, lower)— network edge between two releasing levelsvalidate_firdaria_output(periods)— invariant guard for Firdaria outputvalidate_decennials_output(periods)— invariant guard for Decennials outputvalidate_releasing_output(periods)— invariant guard for Releasing output
Part II — Terminology Standard
§6. Required Terms
The following terms carry specific meanings within this subsystem and must not be used loosely.
| Term | Normative Meaning |
|---|---|
| major period | A FirdarPeriod with level=1; one of the 9 time-lord allocations spanning the full 75-year cycle |
| sub-period | A FirdarPeriod with level=2; a subdivision of a major period |
| sequence kind | The FirdarSequenceKind value determining which planet leads the Firdaria sequence |
| level | An integer 1–4 in Zodiacal Releasing, or 1–2 in admitted Decennials and Firdaria output, identifying the recursive depth of a period |
| Loosing of the Bond | The opposite-sign transfer after a complete subcycle beginning in a long-period sign; preserved as a boolean on the receiving ReleasingPeriod |
| angularity from Fortune | The 1-based sign distance of a releasing period's sign from the natal Lot of Fortune; typed as ZRAngularityClass |
| lot | The natal Lot (Spirit, Fortune, or other) from which releasing proceeds; identified by lot_name only |
| MINOR_YEARS | The immutable sign-to-duration mapping; the arithmetic basis of the releasing technique |
| lord type | The doctrinal classification of a Firdaria planet: luminary, planet, or node; not a concept in Zodiacal Releasing |
| sect light | The luminary of sect that leads the admitted Decennials sequence: Sun by day, Moon by night |
| distribution day | An elapsed lived-day coordinate interpreted inside the 360-day Decennials distribution model |
| calendar projection | A JD/date obtained by adding the distribution-day offset to sequence_origin_jd; not a civil-month anniversary claim |
| deep subdivision method | A compatibility sentinel fixed to None; no selector is admitted and the complete public depth is L1/L2 |
| condition profile | A flat doctrinal summary of a single period, integrating all layers from truth preservation through relational hardening |
| sequence profile | A chart-wide or sequence-wide aggregate derived from a full list of condition profiles |
| active pair | The simultaneous major/sub lord combination at a point in time; a network node in Firdaria |
| active path | The full simultaneously active Decennials lineage from major level to deepest active subordinate level |
| level pair | The structural edge between two adjacent releasing levels at a point in time |
§7. Forbidden Conflations
The following pairs must not be equated.
FirdarPeriod and FirdarConditionProfile
A FirdarPeriod is the raw truth-preservation vessel. A FirdarConditionProfile is
a derived doctrinal summary. One is the source; the other is a projection.
level and depth
level is a 1-based integer field on the period vessel. It is not a synonym for
recursive depth, tree depth, or nesting order. Level 1 is the outermost; Level 4 is
the innermost in Releasing.
major_planet and planet
FirdarPeriod.planet is the time-lord for that period. FirdarPeriod.major_planet
is the planetary anchor of the major grouping to which a sub-period belongs. For
major periods, these are equal. For sub-periods, they differ.
is_loosing_of_bond and is_peak_period
is_loosing_of_bond is a doctrinal Hellenistic designation preserved from the
engine's opposite-sign transfer. is_peak_period is independently derived from
the period's angular place relative to Fortune. Neither flag implies the other.
angularity_from_fortune and ZRAngularityClass
angularity_from_fortune is the raw 1-based integer distance. ZRAngularityClass
is the typed classification derived from that integer. Both are preserved; neither
replaces the other.
FirdarMajorGroup and FirdarSequenceProfile
A FirdarMajorGroup is a relational grouping of one major period with its subs. A
FirdarSequenceProfile is a chart-wide aggregate across all major periods. One is a
local relational structure; the other is a global summary.
sequence_kind (Firdaria) and lot_name (Releasing)
These are both doctrinal identifiers for their respective techniques but they govern
entirely different subsystems and must not be confused or referenced across domains.
DecennialActivePair and DecennialActivePath
The pair is a compatibility surface for the major and first subordinate state. The
path is the full constitutional Decennials network surface for all simultaneously
active admitted levels. They must not be conflated.
Part III — Invariant Register
§8.1 Vessel Invariants
FirdarPeriod:
levelis either 1 or 2planetis a recognized classical planet or node namestart_jd < end_jdlevel=1periods havemajor_planet == planetlevel=2periods havemajor_planetidentifying a recognized level-1 planet
ReleasingPeriod:
levelis 1, 2, 3, or 4start_jd < end_jdangularity_from_fortune, if set, is an integer in the range [1, 12]angularity_class, if set, is a validZRAngularityClassvalue- engine-generated periods carry
fortune_angularity_truth; evaluated raw truth exactly matches all compatibility fields - a missing Fortune produces raw
is_peak_period=Nonewhile the compatibility field remainsFalse
DecennialPeriod:
- construction and admitted engine output allow only
level1 or 2; legacy L3/L4 records are rejected rather than deserialized as valid vessels start_jd < end_jdplanetis one of the seven classical planetslevel=1periods preserve nomajor_planet,parent_planet, orancestor_planetslevel>=2periods preservemajor_planet,parent_planet,parent_level, andancestor_planets- every admitted period has
deep_subdivision_method is None - engine-generated periods carry the same evaluated
sequence_truth; its sequence, sect, sect light, and sequence kind match period metadata
FirdarMajorGroup:
subscontains onlyFirdarPeriodrecords withmajor_planet == self.period.planetsubsis in strict chronological order (enforced in__post_init__)- no two adjacent subs overlap in Julian Day
DecennialMajorGroup:
majoris always aDecennialPeriodwithlevel=1subscontains onlyDecennialPeriodrecords withlevel=2sub_groups, if supplied, align one-to-one withsubs
DecennialPeriodGroup:
periodis always aDecennialPeriodwithlevel>=2- all nested
sub_groupsare exactly one level deeper thanperiod - all nested
sub_groupsremain temporally contained withinperiod
ZRPeriodGroup:
- all sub-groups are temporally contained within
self.period(±1e-6 tolerance) levelequalsself.period.level
FirdarConditionProfile:
lord_typeis one of'luminary','planet','node'years > 0anddays > 0is_node_periodis mutually exclusive withlord_type == 'luminary'
ZRConditionProfile:
years > 0anddays > 0angularity_classisNoneif and only ifangularity_from_fortuneisNone
DecennialConditionProfile:
years > 0,months > 0, anddays > 0lord_typeis one of'luminary'or'planet'- admitted profiles have
level <= 2anddeep_subdivision_method is None
DashaActiveLine (dasha domain — not in scope here): see DASHA_BACKEND_STANDARD.md
§8.2 Truth Invariants
- The
MINOR_YEARSmapping is immutable. No function in this subsystem modifies or overrides it at runtime. FirdarPeriod.sequence_kindisNonefor all level-2 (sub) periods. It is set only on level-1 periods.ReleasingPeriod.is_loosing_of_bondis set by the engine at computation time. It is not a derived property and must not be recomputed from sign names.- The sum of all level-1 Firdaria period durations in a complete sequence equals exactly 75 years (modulo floating-point accumulation).
- The sum of all level-1 Decennials period durations in a complete sequence equals exactly 903 schematic months, or 75 years 3 months, on the admitted 30-day-month / 360-day-year distribution basis.
- All periods in one Decennials sequence preserve the same time-basis and sequence-origin receipt.
- All periods in one Decennials sequence preserve one identical evaluated
DecennialSequenceAssemblyTruth; a non-sect-light longitude tie prevents period generation. DecennialPeriod.sequence_kindis preserved across all admitted Decennials levels.DecennialPeriod.deep_subdivision_methodisNonefor every admitted runtime output; L3/L4 output validation fails closed.- Every engine-generated
ReleasingPeriodpreserves oneZRFortuneAngularityTruthmatching its sign and compatibility projection. Missing Fortune is rawnot_evaluable, not an evaluated non-peak result.
§8.3 Aggregate Invariants
FirdarSequenceProfile:
luminary_major_count + planet_major_count + node_major_count == major_countlen(profiles) == major_count(or greater if sub-profiles are included)total_major_years > 0
DecennialSequenceProfile:
luminary_major_count + planetary_major_count == major_countlevel_count_map[1] == major_countsum(level_count_map.values()) == profile_countdeepest_level == max(level_count_map)deepest_level <= 2deep_subdivision_method is None
ZRSequenceProfile:
angular_count + succedent_count + cadent_countequals the number of profiles classified relative to Fortuneangular_count == peak_period_countperiod_count == len(profiles)total_years > 0
§8.4 Network Invariants
FirdarActivePair:
major_profileis always presentsub_profileisNoneif and only if no sub-period is active at the queried JDis_same_lordis meaningful only whenhas_subisTrue
DecennialActivePair:
major_profileis always level 1sub_profile, when present, is always level 2
DecennialActivePath:
profilesis never empty- the first profile is always level 1
- levels advance one step at a time
- admitted paths have
deepest_level <= 2andhas_deep_subdivision == False
ZRLevelPair:
house_distanceis in the range [1, 12]house_distance = (lower_sign_index − upper_sign_index) % 12 + 1signs_are_identicalisTrueif and only ifhouse_distance == 1and the signs are the same (i.e., the lower level is in the same sign as the upper level)
Part IV — Failure Doctrine
§9.1 Invalid Inputs
Firdaria:
- Passing a non-finite
natal_jdtofirdaria()raisesValueError. - Passing an unrecognized
sequence_kindvalue raisesValueError. - Passing an empty periods list to
group_firdaria(),firdar_condition_profile(), or aggregate/network functions raisesValueError.
Zodiacal Releasing:
- Passing a
lot_longitudeoutside [0, 360) may produce incorrect sign assignments. The subsystem does not clamp or validate this; the caller is responsible. - Passing an empty periods list to aggregate or network functions raises
ValueError.
Common:
- Passing a non-finite
jdtofirdar_active_pair()raisesValueError. - Passing a non-finite
jdtodecennial_active_pair()ordecennial_active_path()raisesValueError.
Decennials:
- Passing a non-finite
natal_jdorcurrent_jdraisesValueError. - Passing missing or non-finite classical natal longitudes raises
ValueError. - Passing an unadmitted deep method or unadmitted deep level raises
ValueError.
§9.2 Search Exhaustion
firdar_active_pair()returnsNoneif no major period is active at the queried JD. This is not an error; it means the queried JD lies outside the 75-year sequence.decennial_active_pair()anddecennial_active_path()returnNoneif no major period is active at the queried JD.current_decennials()raisesValueErrorif the queried JD lies outside the admitted Decennials cycle.ZRPeriodGroup.active_sub_at(jd)returnsNoneif no sub-group contains the JD.
§9.3 Invariant Failure
validate_firdaria_output()raisesValueErrorwith a descriptive message if:- any level-1 period is out of chronological order
- any two adjacent level-1 periods overlap
- any level-2 sub-period references a
major_planetthat has no corresponding level-1 period in the list - any level-2 sub-periods within a major group are out of chronological order or overlap
validate_releasing_output()raisesValueErrorwith a descriptive message if:- periods at any level are out of chronological order
- any level-N+1 period is not temporally contained within its enclosing level-N period
validate_decennials_output()raisesValueErrorwith a descriptive message if:- major periods overlap or are out of order
- subordinate lineage paths are duplicate, unknown, or escape their parent bounds
- parent-lineage truth, major truth, sequence truth, or deep-method truth drifts
- sibling children overlap, go out of order, or fail proportional duration sums
FirdarMajorGroup.__post_init__raisesValueErrorif subs are not in chronological order.DecennialMajorGroup.__post_init__andDecennialPeriodGroup.__post_init__raiseValueErrorif chronology, level, or containment invariants are broken.ZRPeriodGroup.__post_init__raisesValueErrorif any sub-group falls outside the parent period's temporal bounds.
Part V — Determinism Standard
§10. Determinism Guarantees
firdaria()is fully deterministic: given the samenatal_jdandis_day_chart, the output list is identical in every call with no dependency on external state.zodiacal_releasing()is fully deterministic: given the samelot_longitudeandnatal_jd, the output list is identical in every call.decennials()is fully deterministic: given the same natal inputs, levels, and policy, the output list is identical in every call.- Period lists returned by both engines are in strict chronological order by
start_jdwithin each level. The flat list returned byzodiacal_releasing()is ordered by(level, start_jd). group_firdaria(),group_decennials(), andgroup_releasing()are deterministic: they produce identical groupings for identical inputs.firdar_active_pair()is deterministic: given the same periods list andjd, the result is always the same.decennial_active_pair()anddecennial_active_path()are deterministic for identical periods lists and JDs.- All condition, aggregate, and network functions are pure (no side effects, no hidden state).
- Floating-point accumulation across Firdaria sub-period boundaries may produce
end_jdvalues that differ from the major'send_jdby up to a small epsilon. The containment tolerance inZRPeriodGroupandDashaActiveLineis1e-6JD to accommodate this. This tolerance is the only permitted numeric approximation in the subsystem.
Part VI — Validation Codex
§11. Minimum Validation Commands
The following commands must pass without error on any constitutionally correct installation of this subsystem:
.\.venv\Scripts\python.exe -m pytest tests\unit\test_timelords.py tests\unit\test_hellenistic_source_goldens.py -q
All tests in test_timelords.py must pass. The test suite validates:
firdaria(),decennials(), andzodiacal_releasing()correctness- Valens IV.4 same-sign Spirit/Fortune start shift and the exact 211-month Gemini Loosing-of-the-Bond fixture
- source-owned Decennial 129-unit circuit, minor-period allotments, and admitted L1/L2 arithmetic
FirdarMajorGroupgrouping andgroup_firdaria()fidelityDecennialMajorGroupandDecennialPeriodGroupgrouping andgroup_decennials()fidelityZRPeriodGroupnesting andgroup_releasing()fidelity- Chronological ordering guards in
FirdarMajorGroup.__post_init__ - recursive containment and chronology guards in Decennial grouping vessels
- Containment guards in
ZRPeriodGroup.__post_init__ - Subset properties:
luminary_subs,node_subs,planet_subs,is_complete ZRPeriodGroupproperties:is_leaf,angularity_class,all_periods_flat()FirdarConditionProfile,DecennialConditionProfile, andZRConditionProfilefield fidelity- Lord type classification: luminary / planet / node
FirdarSequenceProfile,DecennialSequenceProfile, andZRSequenceProfilecounts, totals, and invariant rejectionFirdarActivePairboundary behavior,Nonereturn, non-finite JD rejectionDecennialActivePairandDecennialActivePathboundary behavior and non-finite JD rejectionZRLevelPairhouse distance, sign identity, peak pair detectionvalidate_firdaria_output()correctness and rejection casesvalidate_decennials_output()correctness and rejection casesvalidate_releasing_output()correctness and rejection cases
§12. Required Validation Themes
Any validation suite for this subsystem must demonstrate the following:
Truth preservation:
- A
FirdarPeriodreturned byfirdaria()carriesplanet,level,major_planet,start_jd,end_jd,years, andsequence_kindwithout truncation or flattening. - A
ReleasingPeriodreturned byzodiacal_releasing()carriessign,ruler,level,lot_name,years,is_loosing_of_bond, andangularity_from_fortunewithout truncation. - A
DecennialPeriodcarries one consistenttime_basis,calendar_projection_basis,sequence_origin_jd, and distribution-day interval without forcing consumers to infer them from JD arithmetic. - The Valens IV.4 fixture preserves its source receipt separately from the expected same-sign start shift and exact Loosing-of-the-Bond boundaries.
Relational integrity:
- All sub-periods in a
FirdarMajorGrouphavemajor_planetmatching the group's major period'splanet. - All subordinate periods in a
DecennialMajorGrouporDecennialPeriodGroupremain temporally contained inside their parent lineage. - All
ZRPeriodGroupsub-groups are temporally contained within the parent.
Classification correctness:
FirdarSequenceKinddiscriminates DIURNAL vs. NOCTURNAL variants correctly.DecennialSequenceKinddiscriminates the diurnal solar vs. nocturnal lunar sequence correctly.ZRAngularityClassdiscriminates ANGULAR / SUCCEDENT / CADENT based on the 1-based distance from Fortune.
Aggregate integrity:
luminary_major_count + planet_major_count + node_major_count == major_countin anyFirdarSequenceProfileconstructed from a valid sequence.luminary_major_count + planetary_major_count == major_countin anyDecennialSequenceProfileconstructed from a valid sequence.angular_count + succedent_count + cadent_countequals the number of profiles with a non-null Fortune angularity classification.angular_count == peak_period_count.
Network correctness:
firdar_active_pair()returnsNonefor JDs outside the sequence.firdar_active_pair()raisesValueErrorfor non-finite JDs.decennial_active_pair()anddecennial_active_path()returnNonefor JDs outside the sequence.decennial_active_path()preserves a contiguous active lineage fromL1to the deepest active admitted level.ZRLevelPair.house_distanceis computed as(lower − upper) % 12 + 1.
Hardening:
validate_firdaria_output()detects out-of-order level-1 periods.validate_firdaria_output()detects overlapping level-1 periods.validate_firdaria_output()detects sub-periods outside their major group.validate_decennials_output()detects lineage drift, deep-method drift, and proportional-sum failure.validate_releasing_output()detects level-N+1 periods outside level-N boundaries.validate_releasing_output()detects out-of-order periods at any level.
Part VII — Future Boundary
§13. Explicit Non-Goals
The following are explicitly outside the scope of this subsystem as constitutionalized.
Not in scope:
-
Chart calculation. The subsystem does not compute natal positions, house cusps, ascendants, or Lot longitudes. These are delegated to the chart engine.
-
Sect determination. Whether a chart is diurnal or nocturnal is computed externally and passed as
is_day_chart. The subsystem does not verify this. -
Lot formula. The formula for computing the Lot of Fortune or Spirit is not defined here. Only the resulting longitude is consumed.
-
Predictive interpretation. The subsystem produces structural timing data. It does not assess whether a period is favorable, challenging, or significant. Interpretation is a higher-level concern.
-
Tropical vs. sidereal zodiac. Zodiacal Releasing is computed over the zodiac defined by the caller's longitude input. The subsystem does not enforce a zodiacal framework.
-
Multi-lot releasing. This subsystem constitutionalizes releasing from a single Lot per call. Simultaneous releasing from Spirit and Fortune is an aggregation concern above this layer.
-
Primary Directions. This subsystem covers Firdaria, Decennials, and Zodiacal Releasing only. Primary Directions are a separate technique and a separate subsystem.
-
Triacontaeteris. This adjacent 30-year chronocrator family is outside this standard and is not a release blocker or an incomplete part of the admitted Hellenistic contract.
-
Decennial L3/L4. Both Valens and Hephaistio deep-subdivision lineages are closed exclusions. No named deep method is selectable in the admitted engine or REST request surface. A future expansion would require a new admission project.
-
Transit and progression overlay. Correlating time-lord periods with transit or progression charts is a cross-subsystem concern and is not part of this standard.
-
Hellenistic bound lord or triplicity lord at period boundaries. These are additional doctrinal overlays that could be computed from natal positions and period boundaries but are not part of the current Firdaria or Releasing subsystems.
Any future extension that crosses these boundaries requires a new constitutional phase or a separate subsystem constitutionalization, not an in-place amendment to this standard.