Transit Engine — High-Level Design
Status: Draft for review · Part of: Astro Composer · Updated: 2026-10-24
The transit engine compares a moving sky against an immutable reference chart: gochara (transit) positions from the natal Moon, Sade Sati phases and ashtakavarga scores, returned as occupancy segments, ingress events and phase intervals. It does pure comparison over binder positions and a verified snapshot: no natal recalculation, no provider call, no clock.
1. Purpose
A transit is not a new chart. It compares a fixed reference chart against a body’s position at an explicit instant. Every answer — which house Saturn occupies, when Sade Sati ends, how many bindus (score points) Jupiter carries — depends on that reference staying fixed. Mix references or conventions and two transit views disagree while both are arithmetically correct.
The transit engine exists so that:
- one immutable reference supplies the Moon sign, lagna sign and natal ashtakavarga;
- a window becomes segments and boundary events, not a row per day;
- ingresses and Sade Sati phase changes are solved to instants;
- gochara comes from the natal Moon, never the lagna;
- responses name reference versions and boundary precision.
2. Where it sits
reference chart · Moon · lagna · BAV ──┐
window or asOf · bodies · step ────────┼──▶ transit engine ──▶ segments + events + phases
binder positions or timeseries ────────┤
profile + rulebook ────────────────────┘
- Upstream: the composition facade supplies a verified reference chart (usually a stored snapshot from the chart/account domain), an explicit
asOfor window, the requested bodies, one profile and one rulebook handle; the binder client supplies transiting longitude, speed and sign id. - Downstream: the facade builds
POST /v1/transits; product views, notification jobs and strength readers consume the same segments and phases. - Never: it does not compose a natal chart, call a provider, read a clock, store a chart or interpret a transit.
Input contract
| Input | Source | Used for |
|---|---|---|
| Reference chart | Chart/account snapshot or chart core | Natal Moon sign, lagna sign, body signs, BAV/SAV |
| Reference versions | Reference chart metadata | Profile, rulebook hash and binder engine equality |
asOf or from/to |
Request | Snapshot instant or scan window; always explicit |
step |
Request | Grid spacing for the scan; default one day, bounded |
| Bodies | Request and profile | Which transiting bodies and in which canonical order |
| Profile | Request | Sade Sati basis (C15), vedha (C16), reduction flag (C17) |
| Rulebook handle | Registry | Gochara verdicts, vedha pairs, BAV contributions, limits |
| Binder positions | Binder POST /v1/positions |
One instant for a snapshot |
| Binder timeseries | Binder POST /v1/timeseries (proposed) |
Grid plus speeds for a window |
| Boundary probes | Facade through the binder client | Refined instants for ingress and phase changes |
Output contract
| Output | Shape | Read by |
|---|---|---|
reference |
Chart hash, profile/rulebook/binder ids, Moon and lagna signs | Response, audit |
asOf or window |
Echo of the explicit request instant or range | Response |
bodies[] |
Snapshot rows: body, sign, houses, verdict, vedha, bindus | Snapshot response |
segments[] |
Body, sign, start, end, house from Moon, bindu score | Timeline view, notifications |
events[] |
Ingress, Sade Sati phase change, direction change | Timeline markers |
sadeSati |
Phase intervals, current phase, window clipping flags | Response, notifications |
ashtakavarga |
BAV/SAV for the reference and savTotal when requested |
Response, strength readers |
boundaryPrecision |
Exact or step, probe count, clipped window | Audit and fixtures |
diagnostics |
Missing reference facts, version mismatch, unsupported layer | Facade errors and flags |
3. Responsibilities
Each area owns one comparison and one deterministic rule.
| Area | Owns | Deterministic rule |
|---|---|---|
| Reference admission | Required chart facts and version equality | Same profile, rulebook hash and binder engine; no mixed conventions |
| Series acquisition | One immutable grid of binder positions | Facade fetches; engine never retries or caches |
| Segment scan | Sign occupancy spans | Compare binder sign ids; never floor(longitude / 30) |
| Ingress solve | Exact sign and 45° crossings | Bracketed root with a Newton step on speed; half-open |
| Gochara | House from the natal Moon and a verdict | ((transitSign − moonSign) mod 12) + 1; rulebook table |
| Vedha | Obstruction pairs that cancel a good transit | Optional; base and effective verdict both reported |
| Sade Sati | Saturn through 12th, 1st and 2nd from the Moon | Profile basis; repeated phase intervals kept |
| Ashtakavarga | Natal BAV/SAV and the transiting sign’s bindus | Computed from the reference chart; SAV total is 337 |
| Assembly | Ordering, clipping and precision | Canonical bodies; segments by start; one rounding point |
4. Architecture
Diagram: reference design, not deployed behaviour.
The engine holds one immutable reference and one immutable input series. Neither is composed or fetched here; both arrive through the facade. That split keeps a transit response reproducible while the sky moves.
5. Rules
- A transit is a comparison. The reference chart is immutable; the engine never resolves a second reference, recomputes a natal position or uses the lagna for the Moon.
- Gochara is from the natal Moon. House number is the sign distance from the Moon sign; lagna-based numbers are informational only.
- Strict reference equality. Profile, rulebook hash and binder engine version must agree; a mixed pair is rejected with
REFERENCE_VERSION_MISMATCH. - There is no “now”. A snapshot needs
asOf, a scan needsfromandto; server time is never an input or a cache key. - No natal recalculation. Moon sign, lagna sign, body signs and ashtakavarga come from the verified reference; birth data is never read.
- Sign assignment is binder-owned. Each grid point carries the binder’s sign id; the engine compares ids, never longitudes.
- Boundaries are solved, not grid-snapped. A segment starts at the ingress instant, belongs to the entering sign, and ends at the next ingress or the window edge.
- A window is segments and events. The response is occupancy spans and boundary instants, not one row per day; a requested step stays bounded.
- Timeseries is transport, not semantics. A grid with speeds and per-instant calls give the same result. Without timeseries the window layer is unsupported; the engine never interpolates.
- Ashtakavarga is natal. A transiting planet scores the bindus the reference assigns to its sign. BAV is never computed from transits, and SAV must total 337 or the rulebook load gate fails.
- Sade Sati has a pinned basis. The profile chooses Moon-sign phases or the 45° arc before the Moon; a retrograde re-entry is a new interval, never merged.
- Vedha is visible. With vedha enabled, the response carries base verdict, effective verdict and cancelling pair; a cancellation never erases the original fact.
- Limits are explicit. Maximum window, body count and minimum step are checked before binder work; exceeding one is
LIMIT_EXCEEDED, not a truncated scan. - Deterministic order and precision. Bodies follow canonical order, segments sort by start, and boundaries round once to the second; no approximate boundary is silent.
- No interpretation. The engine returns houses, verdicts, bindus and intervals; wording, ranking and remedies belong to the product.
6. Edge cases
Bad input fails loudly; nothing is silently approximated.
| Case | Behaviour |
|---|---|
| Reference chart lacks the Moon sign | INSUFFICIENT_INPUT; gochara and Sade Sati are undefined |
| Reference chart from another profile or rulebook | REFERENCE_VERSION_MISMATCH |
| Reference chart from an older binder engine | Reject; the facade may recompose both charts under the current engine |
| Tropical reference profile | LAYER_UNSUPPORTED; gochara and Sade Sati require sidereal signs |
| Window start equals or exceeds end | 400 validation error; no empty success that hides a bad range |
| Window exceeds the configured cap | LIMIT_EXCEEDED before any binder call |
| Requested step below the minimum | LIMIT_EXCEEDED; no silent step substitution |
Sade Sati already active at from |
First phase has startedBeforeWindow: true; the real start is not fabricated |
Sade Sati continues past to |
Last phase has continuesAfterWindow: true |
| Saturn retrogrades across a phase boundary | A separate phase interval is emitted; no merge |
| Sade Sati not active in the window | active: false and an empty phase list; not an error |
| Body enters and leaves a sign inside one step | Speed sign change brackets a station and the crossing is refined; no silent merge |
| Ingress exactly at a grid instant | Half-open rule starts the new segment at that instant |
| Ingress exactly at the window boundary | The segment starting at from belongs to the entering sign; no duplicate event |
| A body has no BAV, such as Rahu or Ketu | bindus: null; never a fabricated zero |
| Ashtakavarga layer not requested | BAV and SAV are omitted; no placeholder values |
| SAV total is not 337 | Rulebook load fails; no partial ashtakavarga is served |
| Vedha table absent from the rulebook | vedha is omitted and the base verdict stands |
| Reference uses cusp houses | Gochara still uses the Moon sign; lagna house is null when cusp placement is unavailable |
| Timeseries endpoint unavailable | Window layer LAYER_UNSUPPORTED; a snapshot may still use positions |
| Binder reports degraded precision | Response is marked degraded with the binder’s precision, not silently normalised |
| Probe budget exhausted while solving | Internal failure with a correlation id; no approximate ingress |
| Window spans an ephemeris coverage edge | Binder range error propagates with the layering context added |
7. Out of scope
- Natal chart assembly, chart frame, dignity and vargas (chart core, varga engine).
- Vimshottari periods and dasha-based transit weighting (dasha engine).
- Panchang and muhurta windows (panchang engine).
- Ashtakoota matching (matching engine).
- Western transits, progressions, returns, synastry and composite charts.
- Transit interpretation, predictions, remedies and favourable-period prose.
- Eclipse, station and retrograde forecast products.
- Declination, parallels and aspect geometry (binder semantics, later profiles).
- Storing charts, snapshots or transit reports (chart/account domain).
- Binder access, caching, retries and provenance (facade and binder).
8. Planned code
| Piece | Responsibility |
|---|---|
transit/TransitEngine |
Admission, snapshot or scan mode, assembly |
transit/ReferenceAdmission |
Required facts and strict version equality |
transit/TransitSeriesScanner |
Grid scan, sign occupancy and direction changes |
transit/IngressSolver |
Sign and 45° crossing instants with a probe budget |
transit/GocharaResolver |
Moon-referenced house and rulebook verdict |
transit/VedhaResolver |
Obstruction pairs and base/effective verdicts |
transit/SadeSatiTracker |
Phase intervals, repeats and window clipping |
transit/AshtakavargaScorer |
Natal BAV/SAV, 337 check and transit bindus |
transit/TransitAssembler |
Segments, events, ordering and precision |