Muhurtam election-chart screening
This page defines the source-backed chart screen that follows the browser's existing Panchangam and personal Muhurtam ranking. It answers four separate questions without collapsing them into one opaque score:
- Which candidate windows survive the existing day, slot and personal gates?
- Which source statements can be expressed as deterministic predicates, either directly or through a named, versioned interpretation convention?
- Does each predicate reject a window, qualify its displayed tier, or supply tie-break evidence?
- Which source statements or chart facts remain genuinely unresolved after that computation?
Assurance boundary: a chart-screened result has passed the automated predicates listed below at the start, final represented minute, each 10-minute cadence point, and both sides of every known local Drik/Lahiri Lagna transition inside the offered window. The browser recomputes Whole Sign houses from the sidecar's planetary Rashis in that local Lagna frame. A window that only partly overlaps the five-minute transition guard at an edge is retained for review, never hard-rejected or promoted by a Lagna-dependent rule. It is not a complete election, a continuous-time proof, a compatibility reading, or a professional recommendation. A high relative tier still means “best among the candidates evaluated,” not universally auspicious.
Completion boundary: “resolved” means only that every implemented, event-specific predicate for the selected activity has a conclusive outcome. It does not mean that the inherited general election-chart baseline is complete. That separate program remains tracked in #284.
Architecture and data minimization
The browser already has the selected city and locally stored, derived profile facts. Personal rules run in the browser. The remote chart request deliberately contains neither a person nor an activity; the returned candidate-time charts are evaluated against the generated rule table locally.
flowchart LR
BASE["Panchangam and personal scorer<br/>ordered candidate windows"]
ROLE["Selected local role<br/>derived natal facts only"]
BATCH["Browser batch<br/>up to 24 sampled instants"]
GATE["Astro guest gateway<br/>validation, CORS, rate limit"]
SIDE["Authenticated DashaFlow sidecar<br/>Lahiri planetary positions"]
LAGNA["Validated local Lagna map<br/>selected city and minute"]
PROJECT["Local Whole Sign projection<br/>planet Rashi relative to Lagna"]
RULES["Generated deterministic rules<br/>evaluated in browser"]
OUT["Reject failures<br/>cap unmet qualifications<br/>tie-break preferences<br/>show unknowns"]
ROLE --> BASE
BASE --> BATCH --> GATE --> SIDE --> GATE --> PROJECT --> RULES --> OUT
LAGNA --> BATCH
LAGNA --> PROJECT
Activation and release boundary
The browser implementation and deterministic rules can be reviewed without activating a public network capability. Public builds fail closed unless VITE_ELECTION_CHART_API_ENABLED is the exact, case-sensitive string true. Whitespace, alternate casing, empty strings and other values disable the capability. With no flag, requests are enabled only on localhost, 127.0.0.1, or [::1] for local development. This flag is independent from VITE_BIRTH_PROFILE_API_ENABLED; enabling one calculation journey does not enable the other.
The production build sets that flag together with the birth-profile flag after the owner approved paired public activation. The exact Production Astro deployment at public revision 4106f097 returned 200 for a synthetic election chart and retains an independent server-side kill switch. Public Nominatim remains unavailable in Preview by design. See the production activation runbook for exact deployment, perimeter and rollback evidence.
When disabled, the browser does not create a request controller, register a timeout or call fetch. It retains the Panchangam shortlist, caps any Excellent label at Good, marks the result for review, and states that exact chart screening is not active in that build. Public requests, when explicitly enabled, can use only the canonical https://astrochaganti.com/api/guest HTTPS base. Loopback, arbitrary-host, credential-bearing, query, fragment, port and path overrides are rejected. VITE_ELECTION_CHART_API_BASE therefore cannot point a deployed client at an Astro Preview today. The browser flag is not server authorization; the gateway and sidecar must be activated independently under their own release approval.
When explicitly active, the public browser calls POST /api/guest/muhurta/election-charts. The gateway forwards a narrow authenticated request to the sidecar's POST /v1/election-chart/derive contract. Both layers are stateless for this operation and responses use no-store caching directives.
| Data category | Network treatment |
|---|---|
| Contract version | Sent so an incompatible response fails closed. |
| Candidate city | Latitude, longitude and IANA timezone are sent because Lagna is location-dependent. The free-form place label is not sent. |
| Candidate times | Up to 24 unique minute-precision RFC 3339 UTC instants are sent in request order. |
| Activity | Not sent. Rule selection occurs in the browser. |
| Profile identity | Name, profile ID and selected role are not sent; the gateway rejects these fields. |
| Birth data | Date, time, birthplace, Nakshatra, Janma Rashi, Janma Lagna and natal chart are not sent; the gateway rejects birth and natal fields. |
| Response | Contract/engine metadata including the required mean node convention, echoed location, and one sidecar Lagna plus nine-graha snapshot per instant. Planetary Rashis and degrees are retained; browser decisions recompute houses against the validated local Lagna map. |
| Browser storage | Candidate-time charts are never written to localStorage. The selected role is a versioned, bounded activity-to-stable-profile-ID preference stored only in this browser; it is reconciled after profile edit/deletion and is never sent, included in shared text, or exported. |
The request uses credentials: omit and cache: no-store. The public gateway also enforces a 4 KiB body cap, strict origin policy, rate limiting and exact response validation. Network and hosting providers still process the narrow request in transit; “data-minimized” does not mean “no network calculation.” The reviewed gateway stack combines each guest route's process-local guard with atomic limits in the existing Turso database shared across Vercel instances and fails closed if that layer is missing or unavailable. Limiter rows contain only pseudonymous counter keys and integer timing/count fields; election charts and birth/profile data are not stored there. No Upstash or Redis service is part of this release. Candidate code is not evidence that it is merged, configured, deployed, or operationally certified.
The related guest place-search route has an additional durable fairness guard: after the five-request-per-minute client limit, request validation, cache lookup, and duplicate coalescing, one client may make at most 50 valid managed-provider cache misses in an anchored 24-hour window. This guard has its own bounded two-second storage deadline. Malformed requests and reusable results do not spend that allowance, though malformed requests may already spend the earlier route guards. Fifty is nominally 5% of the configured 1,000-attempt public-Nominatim pool and prevents one client identity from exhausting it, though an anchored-window reset can permit up to 100 upstream attempts in one provider UTC day. A public-Nominatim 429 also persists its bounded numeric or HTTP-date Retry-After fleet-wide through exact-fence completion, up to 24 hours; missing, malformed, past, or zero-delay guidance becomes 60 seconds. These place-search controls support profile creation but do not change the election-chart request or scoring contract below.
Astronomical contract
The chart service returns:
- DashaFlow engine name and version;
- the actual ephemeris state reported by the calculation (
swiss,moshier,mixed, orunknown); Lahiriayanamsha;- the contract-bound
meanlunar-node convention; - sidecar Whole Sign houses and Lagna, retained for contract diagnostics but not used as the browser's house authority; and
- exactly the ordered tuple
Surya,Chandra,Kuja,Budha,Guru,Shukra,Shani,Rahu,Ketu; the separate node convention makes Rahu the mean node.
mixed means the screening run did not use one uniform ephemeris state across every snapshot or accepted service batch; it must be disclosed rather than simplified to swiss or moshier. The same derivation and licensing caveats as the guest D1 chart apply; see Guest birth profiles and the D1 Rashi chart. For a vacancy predicate, all nine returned grahas count as occupants, including Rahu and Ketu. The network adapter accepts only one complete set of those nine canonical names with canonical Rashis and integer houses 1–12. It also checks response order, exact input instants, echoed location, DashaFlow, Lahiri, mean-node and Whole Sign metadata. One missing, duplicated, reordered or unrecognized value rejects the entire batch as an invalid response. Planet and Lagna degrees must match the sidecar's two-decimal projection (including its representable value immediately below a rounded 30° boundary); each returned house must agree with the returned Whole Sign Lagna; Surya and Chandra must be direct; and retrograde Rahu/Ketu must remain opposite within the combined 0.01° rounding envelope. A contradiction fails the batch closed. Before a predicate runs, the browser resolves the local Lagna Rashi for the exact sample minute and recomputes every graha's Whole Sign house as:
H(p) = ((RashiIndex(p) - LocalLagnaIndex + 12) mod 12) + 1The sidecar's returned planet.house and Lagna Rashi cannot override this frame. A missing or invalid minute-to-Lagna mapping rejects the affected service batch before it can contribute outcomes. If no earlier batch completed, the UI falls back to the unscreened shortlist with state unavailable; after one or more batches completed, the partial-run rules below apply. It never uses the valid-looking part of a malformed batch.
Engine provenance is also a run-wide invariant. Name, version, ayanamsha and node convention must remain identical across accepted batches; an incompatible later batch is rejected before any of its windows are applied. Ephemeris is the only aggregating field: differing accepted ephemeris disclosures are preserved as mixed.
The pure Python and TypeScript predicate evaluators separately fail closed to unknown if a caller invokes them directly with an incomplete chart. That is a unit-level defensive state, not the public network behavior described above.
Drik/Lahiri-only boundary
The sidecar contract is a Lahiri sidereal, Whole Sign, DashaFlow calculation. It is therefore used only when the website's selected system is drik. A Surya Siddhanta or Vakya search keeps its independently ranked shortlist and is labelled unsupported-system; the application does not silently mix a Drik/Lahiri chart into another system.
This boundary is about compatible conventions, not implementation identity. The DashaFlow sidecar is not asserted to be the same implementation as the repository's frozen Drik engine. The returned engine and actual ephemeris metadata must remain visible for verification.
Independent calculation verification
The positional contract was checked on 2026-08-29 against dated Drik Panchang sidereal-position pages, not only against repository fixtures. Those pages state that the displayed clock is local and DST-adjusted, the zodiac is sidereal, Lahiri/Chitrapaksha is the default ayanamsha, and the displayed Rahu and Ketu are mean positions unless changed to the separately listed true-node values. The comparison used the exact minute shown in each dated URL and the page's GeoNames location.
| Reference | Drik Panchang | DashaFlow projection | Result |
|---|---|---|---|
| Hyderabad, 2026-08-27 13:48 IST | Vrischika Lagna 27°32′; nine grahas | Vrischika 27.36°; every graha in the same Rashi | Pass |
| Hyderabad, 2026-08-28 03:39 IST | Karka Lagna 7°05′; nine grahas | Karka 6.91°; every graha in the same Rashi | Pass |
| Washington, D.C., 2026-07-14 03:30 EDT | Vrishabha Lagna 24°10′; nine grahas | Vrishabha 24.39°; every graha in the same Rashi | Pass |
| Hyderabad, 2026-01-15 10:19 IST | Meena Lagna 0°11′ | Kumbha 29.98°; planetary Rashis still agree | Known Lagna-boundary divergence; local frame and review guard apply |
| Sydney, 2026-05-28 14:35 AEST | Tula Lagna 0°03′ | Kanya 29.48° and remains Kanya at 14:36 | Known Lagna-boundary divergence; local frame and review guard apply |
All 27 interior planet comparisons agreed on Rashi. Degree-within-Rashi differences were at most 0.01° for planets after the sidecar's two-decimal projection and 0.23° for Lagna; the locked regression permits 0.03° and 0.30° respectively. Those interior cases verify the planetary sign inputs used by the implemented predicates; they do not establish exact Lagna-boundary identity. The two boundary captures demonstrate why the local Lagna projection and review guard are part of the public computation contract. None of these comparisons is a claim of sub-arc-minute identity. The sidecar stores the captured external values, exact URLs, conventions and coordinates in tests/fixtures/election_chart_drikpanchang_capture.json and recomputes all three interior cases in its contract suite without making a live network request. The two known boundary differences are locked separately as negative-equivalence fixtures: a future interior match cannot be reported as proof that the two Lagna conventions are identical at transitions.
Boundary-guard audit
The five-minute guard is also backed by a reproducible local sweep, not chosen from the two named examples alone. The committed audit compares the generated lagna.json minute boundary with the same PySwissEph sidereal-Lahiri Whole Sign Ascendant primitive and flags used by DashaFlow 1.1.0. Its fixed product envelope is all 22 supported cities on the 15th of every month from January 2025 through December 2032:
| Audit result | Measured value |
|---|---|
| City-dates | 2,112 |
| Distinct first-cycle Lagna transitions | 25,344 |
DashaFlow first carried the published new Lagna at T / T+1 / T+2 | 3,334 / 18,865 / 3,145 |
Later than T+2 | 0 |
| Maximum continuous boundary delta | 1.61088 minutes |
| Remaining margin inside the ±5-minute guard | 3.38912 minutes |
| Minimum dwell between audited adjacent transitions | 51 minutes |
The maximum occurred at Tirupati on 2028-05-15 for the published 16:15 Tula transition. The minimum dwell occurred at London on 2025-01-15. The machine- readable report is tests/fixtures/lagna-boundary-guard-audit.json; the default Python suite recomputes and compares the whole report, so tools/verify_project.py cannot pass with a stale boundary claim. The standalone equivalent is:
.venv/bin/python tools/audit_lagna_boundary_guard.py \
--verify tests/fixtures/lagna-boundary-guard-audit.jsonSome already-published or cached days expose a second-cycle tail beyond the first 12 advances. A sub-minute final window can also have its start and end round to the same exclusive cycleEnd minute. The current generator omits that zero-width row; the browser accepts it only as the final sequential row for compatibility with existing artifacts, while keeping the half-open cycle and all malformed interior data fail-closed. This audit deliberately measures one complete zodiac cycle—exactly 12 distinct boundaries per city-date—so the guard evidence is not inflated by duplicates and does not certify that separate artifact-shape behavior.
Exact automated-rule matrix
The canonical table is telugu_panchangam.personal.election_chart_rules.ELECTION_CHART_RULES. tools/export_election_chart_rules.py projects it to the browser; the generated JSON is not an independent authority. There are 32 deterministic predicates across 15 activity profiles.
Reject means a failed predicate removes the window. Prefer means a passing predicate is tie-break evidence only; it adds no raw score and its absence does not reject the window. Qualify means a positive event condition must pass across the sampled window for an Excellent label. A known failure retains the window, leaves its raw score unchanged and makes Good the maximum displayed tier; it is a conclusive event-specific condition miss, not a practitioner-review state. An unresolved calculation boundary or missing fact also retains the window with unchanged raw score and a maximum Good tier, but remains review-gated. A slot may have a conclusive miss in one rule and a separate unknown in another, so capped and review-gated counts are not mutually exclusive; the result reports the exact overlap rather than implying that those counts represent unique slots.
Every generated predicate carries both its source_claim and a claim-specific source_locator (chapter/section plus internal printed and physical PDF page, or verse plus printed page). The UI displays that locator with the computed outcome; a generic book title is never substituted for the exact rule location. A rule that requires interpretation also carries a separate convention_id, formula, and method-claim IDs. Its ranking effect carries a separate decision-policy claim when the source wording does not itself define that effect, as with Gold qualification and the Annaprasana Lagna preference. The event source, interpretation sources and product policy remain independently inspectable; none acquires another layer's authority merely by appearing in the same result.
The same Python module owns ELECTION_CHART_MANUAL_REMAINDERS and the versioned ELECTION_CHART_COMPLETE_ASSESSORS declaration. Gold, Annaprasana, and Karnavedha are the currently declared complete event-specific assessors. Aksharabhyasa has no Chapter VIII event-clause remainder, but it is intentionally not declared complete because the shared general election-chart baseline remains provisional. The browser may name an assessor complete only when its declaration, rule outcomes, boundaries, candidate budget, and remainder all support that claim.
For each screened activity, the remainder table contains only the qualitative clauses left after the predicates below; this prevents the result card from asking a practitioner to re-check the exact condition it just computed. Non-Drik, unavailable and Python/MCP results retain their original full manual_checks disclosure.
Let H(p) be the locally recomputed Whole Sign house of graha p using the validated selected-city Lagna frame, R(p) its Rasi, N(p) its derived Navamsa, G the complete nine-graha set, and S a listed set of houses. The eight supported predicate kinds are exactly:
house_empty(h) = every p in G has H(p) != h
planet_not_house(p, h) = H(p) != h
planet_in_houses(p, S) = H(p) is in S
any_planet_in_houses(P, S) = at least one p in P has H(p) in S
all_planets_in_houses(P, S) = every p in P has H(p) in S
planet_well_situated(p, C) = no adverse factor selected by convention C
planet_receives_full_aspect(p) = at least one listed classical graha casts a
full whole-sign Graha Drishti to R(p)
house_free_of_natural_malefics = no configured natural malefic occupies house 1The first five predicates are direct configured occupancy tests. The sixth and seventh exist only for Gold v1 and name the interpretation conventions that define dignity, natural relationship, Navamsa, solar clearance and full-aspect geometry. Annaprasana adds the eighth predicate kind, house_free_of_natural_malefics, whose exact malefic set, node choice, Paksha formula and precision guard are named separately below. No unpublished orb, functional-benefic, house-lord or composite-strength model is hidden behind these predicates.
| Activity | Rule ID | Deterministic predicate | Effect | Source claim |
|---|---|---|---|---|
| Wedding | wedding.house-7-vacant | None of the nine grahas occupies house 7 | Reject | muhurta.wedding |
| Wedding | wedding.kuja-not-8 | Kuja is not in house 8 | Reject | muhurta.wedding |
| Wedding | wedding.shukra-not-6 | Shukra is not in house 6 | Reject | muhurta.wedding |
| Annaprasana | annaprasana.house-10-vacant | House 10 is vacant | Reject | muhurta.annaprasana.raman_transcription_chart |
| Annaprasana | annaprasana.budha-not-7 | Budha is not in house 7 | Reject | muhurta.annaprasana.raman_transcription_chart |
| Annaprasana | annaprasana.kuja-not-8 | Kuja is not in house 8 | Reject | muhurta.annaprasana.raman_transcription_chart |
| Annaprasana | annaprasana.shukra-not-9 | Shukra is not in house 9 | Reject | muhurta.annaprasana.raman_transcription_chart |
| Annaprasana | annaprasana.benefic-occupies-lagna | At least one of Budha, Guru or Shukra physically occupies house 1 | Prefer | muhurta.annaprasana.raman_transcription_chart |
| Annaprasana | annaprasana.no-natural-malefic-in-lagna | No configured natural malefic physically occupies house 1 | Reject | muhurta.annaprasana.raman_transcription_chart |
| Karnavedha | karnavedha.house-8-vacant | House 8 is vacant throughout the sampled candidate window | Reject | muhurta.karnavedha |
| Seemantha | seemantha.house-8-vacant | House 8 is vacant | Reject | muhurta.seemantha |
| Seemantha | seemantha.chandra-not-8 | Chandra is not in house 8 | Reject | muhurta.seemantha |
| Gruhapravesha | gruhapravesha.house-8-vacant | House 8 is vacant | Reject | muhurta.gruhapravesha |
| Land purchase | property.guru-kendra-trikona | Guru is in 1, 4, 5, 7, 9 or 10 | Prefer | muhurta.land_purchase.building |
| Land purchase | property.kuja-11 | Kuja is in house 11 | Prefer | muhurta.land_purchase.building |
| Land purchase | property.kuja-not-lagna | Kuja is not in house 1 | Reject | muhurta.land_purchase.building |
| Completed-house purchase | house-purchase.kuja-not-lagna | Kuja is not in house 1 | Reject | muhurta.house_purchase.completed |
| Gold / jewelry | gold.surya-well-situated | Surya passes the disclosed Phaladeepika well-placed v1 placement tests | Qualify | muhurta.gold_jewelry.purchase |
| Gold / jewelry | gold.chandra-well-situated | Chandra passes the disclosed placement, Navamsa and solar-clearance v1 tests | Qualify | muhurta.gold_jewelry.purchase |
| Gold / jewelry | gold.surya-fully-aspected | Surya receives at least one full classical Graha Drishti under v1 | Qualify | muhurta.gold_jewelry.purchase |
| Gold / jewelry | gold.chandra-fully-aspected | Chandra receives at least one full classical Graha Drishti under v1 | Qualify | muhurta.gold_jewelry.purchase |
| Aksharabhyasa | vidyarambha.house-8-vacant | None of the nine grahas occupies house 8 | Reject | muhurta.vidyarambha |
| Aksharabhyasa | vidyarambha.budha-shukra-guru-9 | Budha and Shukra and Guru each occupy house 9 | Prefer | muhurta.vidyarambha; election_chart.vidyarambha_co_location_policy_v1 |
| General purchase | purchase.chandra-lagna | Chandra is in house 1 | Prefer | muhurta.purchase.general |
| General purchase | purchase.shukra-lagna | Shukra is in house 1 | Prefer | muhurta.purchase.general |
| Entering service | job.surya-or-kuja-10-11 | Surya or Kuja is in house 10 or 11 | Prefer | muhurta.service_entry |
| Shantika / Paushtika | ceremony.surya-10 | Surya is in house 10 | Prefer | muhurta.shantika_paushtika |
| Shantika / Paushtika | ceremony.chandra-4 | Chandra is in house 4 | Prefer | muhurta.shantika_paushtika |
| Shantika / Paushtika | ceremony.guru-lagna | Guru is in house 1 | Prefer | muhurta.shantika_paushtika |
| Pilgrimage | pilgrimage.guru-lagna-or-9 | Guru is in house 1 or 9 | Prefer | muhurta.pilgrimage |
| Travel | travel.kuja-not-8 | Kuja is not in house 8 | Reject | muhurta.travel |
| Surgery | surgery.house-8-vacant | House 8 is vacant | Reject | muhurta.surgery |
Gold's event clause comes from B. V. Raman, but its operational definitions do not. The phaladeepika-well-placed-v1 convention selects Phaladeepika II.36's adverse-placement categories, I.6's fall signs, II.21–22's natural relationships, BPHS 6.12's Navamsa sequence, Whole Sign houses, and a disclosed 12° Chandra solar-clearance product threshold. Surya-Siddhanta X.1 supplies historical rationale for a 12-degree lunar-visibility boundary, but its units are time-degrees in oblique ascension; v1's shortest-ecliptic-longitude test remains an explicit approximation. The phaladeepika-full-graha-drishti-v1 convention selects the full classical aspects in Phaladeepika II.23, excludes nodes and partial aspects, and reads Raman's unqualified “aspected” literally rather than silently changing it to “benefically aspected.” Exact formulas and boundaries are recorded in Gold / Jewelry.
Annaprasana transcription policy
All six clauses share the exact locator: B. V. Raman, Chapter VIII, “First feeding on rice (Annaprasana),” inspected in the 2020 Chistabo derivative at internal printed page 22 (physical PDF page 25). The public file identifies itself as a Chistabo re-edited transcription with bracketed additions and an omitted appendix; it is not represented as the UBS 1993 print artifact.
whole-sign-physical-occupation-v1 makes “in Lagna” physical Whole Sign house-1 occupation. It does not import the Namakarana passage's separate Lagna-strength instruction. annaprasana-natural-malefic-lagna-v1 fixes the mandatory set to Surya, Mangala, Shani, mean Rahu, mean Ketu and waning Chandra. BPHS 3.11 is registered only as a modern supporting witness for the classification. Budha's conditional association is limited to same-sign occupation; the accompanying malefic already controls the prohibition.
For Chandra in Lagna, v1 uses the Raman transcription's Chapter II split:
E = (longitude(Chandra) - longitude(Surya)) mod 360
0 < E < 180 => waxing; no failure from Chandra
180 < E < 360 => waning; mandatory failure
distance(E, {0, 180, 360}) <= 0.02 degrees => unknownWhole Sign projection, mean nodes, Budha same-sign association, the numeric Paksha formula, the ±0.02° precision guard and effect-aware sampled-window aggregation are individually registered product conventions. A known fixed malefic in Lagna controls even when the Chandra phase cell is unknown.
The source choice is also explicit. Iyer's Kalaprakasika, Chapter III, printed page 34 (public PDF page 66; OCR lines 3305–3317), instead puts Shukra outside the 7th and Budha outside the 9th. Muhurta Chintamani verse 18, printed page 178 (scan page 194), places Chandra outside houses 1, 6 and 8; its commentary on printed page 180 (scan pages 196–197) qualifies the adverse Lagna case to weak or waning Chandra and describes full Chandra in Lagna as favorable. election_chart.annaprasana.raman_transcription_policy_v1 selects Raman's six-clause profile and does not blend either conflicting scheme. It is a project-policy claim with no direct source IDs; the separately registered chart and divergence claims carry the external-source attribution.
Activity-specific personal roles
The generic group scoring treats every selected person as an independent Tara, Chandra and Lagna contributor. Four source passages instead name a governing person. The UI therefore asks for one primary role and, for Drik, evaluates the following source rule from the returned Chandra facts and canonical local Lagna at every sampled state in the same enrichment pass as the general chart predicates:
For an ordered cycle of length N, the inclusive position used by Travel and Seemantha is:
position = ((candidate_index - natal_index + N) mod N) + 1N = 12 for Rasi/Lagna and N = 27 for Nakshatra. Position 1 therefore means the candidate and natal value are the same.
| Activity | Required role | Rule ID(s) | Exact personal rule | Treatment |
|---|---|---|---|---|
| Travel | Primary traveller | personal.travel.lagna-exclusions; personal.travel.janma-rashi-lagna | Count the candidate Lagna inclusively from the traveller's Janma Lagna; reject positions 1, 5, 7 and 9. Matching the traveller's Janma Rashi is one preference. | Existing generic group scoring remains intact. A prohibition in any sampled state rejects; the preference counts only when every sampled state passes. |
| Gruhapravesha | Primary householder | personal.gruhapravesha.natal-anchor-match | A match to the person's Janma Nakshatra, Janma Rashi or Janma Lagna supplies one preference. | Existing generic group scoring remains intact. No match is not a rejection; the preference counts only when every sampled state matches at least one fully resolved natal anchor. |
| Seemantha | Mother | personal.seemantha.birth-star-exclusions | Count candidate Nakshatra inclusively from the mother's birth Nakshatra; reject positions 3, 7, 8, 10 and 22. | Existing generic group scoring remains intact. A prohibited position in any sampled state rejects the window. |
| Surgery | Patient | personal.surgery.chandra-outside-janma-rashi | Reject Chandra in the patient's Janma Rashi. | Existing generic group scoring remains intact. Janma-Rashi Chandra in any sampled state rejects the window. |
Role selection is stored only as a versioned activity-to-stable-profile-ID map in this browser. It survives reload and profile edits, is repaired after deletion, is never exported, shared or sent to the chart service, and is never inferred from a profile name. A one-off manual participant remains session-only. Exactly one role-holder is required for each of these activities; the first selected participant is the initial default and the user can change it. If the role or a required derived natal fact is absent, the source-specific result is unknown, remains visible for review, and cannot be silently treated as a pass. A preference that does not agree across every sample is unknown, earns no tie-break, marks the sampled window unstable and is disclosed as not spanning the full window. For a non-Drik search, these source-specific personal rules are not blended in; the result retains the generic scorer and explicitly requires review.
Boundary and outcome semantics
Candidate windows use minute precision and half-open interval semantics [start, end). Each window begins with its edges and every 10-minute cadence point measured from the start:
start_sample = local date + start minute
cadence = start + 10, start + 20, ... while before end_sample
end_sample = local date + max(start minute, end minute - 1)The cadence is independent of the precomputed transition source. It prevents coverage from depending only on one rounded transition minute. Most predicates depend on Rashi, Nakshatra or Whole Sign house states. Gold v1 additionally uses Navamsa divisions and a solar-clearance threshold; a known adverse state at any sample governs the window, and the documented rounding guards fail closed when a sampled value is too close to a boundary. This remains discrete coverage, not a continuous-time proof.
The sidecar projects graha degrees to two decimals. For Seemantha's mandatory relative-Nakshatra rule, the browser therefore treats the returned Chandra degree as a closed ±0.005° interval. If that interval spans an internal Nakshatra boundary within the returned Rashi, the Nakshatra outcome is unknown: the slot remains visible, earns no preference, and is capped for review rather than being admitted or rejected from rounded evidence.
The browser also reads and validates the selected city's precomputed Drik/Lahiri Lagna transitions. Every sample minute is mapped to its canonical local Lagna, and all nine houses are recomputed from the returned planetary Rashis in that frame. For every transition strictly inside the window it also samples the minute before, the transition minute, and the minute after (deduplicated and clipped to the half-open window). The resulting set therefore covers both edges and both sides of every known interior Drik Lagna boundary. If that boundary data is unavailable, an activity that needs the chart screen does not fall back to endpoint-only assurance: screening is unavailable, the base shortlist is retained, and an otherwise Excellent result is capped for review.
The dated external checks found that Drik Panchang and the sidecar can disagree on the Lagna Rashi for one or two minutes at a transition. A five-minute guard surrounds every local boundary. A window that contains the complete guard on both sides is evaluated across both canonical Lagna states. If the offered window touches only part of that guard at its start or end, every purely Lagna-dependent general predicate is unknown; Travel and Gruhapravesha Lagna rules are also unknown. Gold's placement assessor treats the house factor as unresolved but still evaluates its Rasi, Navamsa and solar-clearance factors: a known adverse factor still produces fail, while the absence of one remains unknown because the house condition is not proved. Gold's full-aspect rules remain computable because they depend on planetary Rashis rather than Lagna. Seemantha and Surgery's Moon/Nakshatra personal rules likewise remain computable. This guard is a conservative containment rule, not a claim that the two implementations share an exact boundary.
The selected city's IANA timezone converts each wall time to an exact UTC instant; the computer's timezone is irrelevant. A slot minute at or above 24:00 rolls into the next selected-city calendar date before conversion. A nonexistent local wall time fails the request rather than fabricating an offset. The adapter preserves exact instant order, and each service batch contains at most 24 unique instants. Windows are packed dynamically, so a request can contain fewer than 12 candidates when their interior Lagna transitions require additional samples. The sidecar accepts only minute-precision instants from 366 days in the past through 1,830 days in the future.
The table below defines the chart-predicate window combiner:
| Condition across every sampled state | Reject predicate | Qualify predicate | Prefer predicate |
|---|---|---|---|
| Pass at every sample | pass; retain | pass; retain without a qualification cap | pass; one tie-break pass |
| At least one known failure | fail; remove; mark unstable if statuses differ | fail; retain and cap below Excellent; mark unstable if statuses differ | fail only when every sample fails; retain with no preference |
No failure, but at least one unknown | unknown; retain for review | unknown; retain for review and cap below Excellent | unknown; retain for review with no preference |
| Known preference statuses differ | Not applicable | Not applicable | unknown; retain for review with no preference |
A complete, valid batch is a precondition for this table. A malformed or incomplete network response does not become a retained unknown; that batch is discarded and the UI reports unavailable. If it is the first batch, the original conservatively capped shortlist remains visible. If a later batch fails, every conclusive removal and survivor from earlier completed batches is preserved: only those already-screened survivors remain visible, while the failed batch and all unprocessed candidates are withheld. The result is labelled partial exact chart screening, never a completed run. Within a valid batch, unknown represents a supported unresolved evaluation: a preference whose status differs across sampled states, a Lagna-dependent rule in a partial boundary-guard window, a rounded Navamsa boundary or the Gold v1 solar-clearance precision guard. For reject and qualify, a known failure in any sample takes precedence over an unrelated unknown; the failure is not hidden by missing evidence elsewhere in the window.
The local personal-role combiner uses the same fail-at-any-sample rule for a prohibition. When a fully resolved personal preference is not present at every sample, it records unknown, retains the window for review, earns no tie-break and marks the sampled window unstable. The shared Python/TypeScript parity fixtures cover both edge and interior-state disagreement.
stable means the predicate statuses agree at every sampled canonical state. It does not mean every instant in the interval was calculated. The cadence plus every known interior Drik Lagna transition materially strengthens whole-window coverage and reduces dependence on one engine's exact boundary minute, but it remains a discrete check rather than proof that no other astronomical status changed and returned between samples.
A chart unknown or an unresolved required personal fact is capped from Excellent to Good and marked practitioner_review. A resolved qualify failure is also capped, but it is labelled as an unmet computed qualification, not practitioner review. Instability by itself is not an unresolved state: a pass/fail Gold qualification is unstable but fully assessed because the known failure governs the window. A hard chart or personal reject failure removes the window. Positive personal preferences and chart preferences never change the raw score. Ordering is:
- tier;
- raw Panchangam/personal score;
- source-specific personal preference passes;
- chart preference passes;
- absence of an already-computed personal dosha;
- date and start time.
The browser dynamically packs the next base-ranked windows into no more than 24 unique instants per request and refills after conclusive candidate removals where possible, returning at most 10 survivors. One search makes at most five chart requests. Because windows can need different numbers of transition samples, the exact candidate count is data-dependent rather than a fixed 60-window guarantee. If that request budget is reached, candidateLimitReached is true and the message states the exact number of highest-ranked candidates that were screened; a short or empty list is not represented as proof that every remaining base candidate was screened. If the chart service is unavailable or its response is invalid before any batch completes, the original Panchangam-ranked top 10 remain visible with an explicit unavailable state; they are not labelled chart-screened. A later failure instead shows only survivors from completed batches, retains their removal accounting, withholds every unscreened candidate, and clearly labels the result partial. If the base scorer produced no candidate, the enrichment state is not-run and no chart request is made. An intentionally inactive build uses the separate disabled state with the same conservative shortlist and rating cap, so a release decision is never misreported as a service outage.
Removal accounting is exclusive and ordered: a window rejected by its exact personal-role rule is counted as a personal removal and is not evaluated again as a chart removal. The remaining windows are then evaluated against the general chart rules, so the two removal counts never double-count one window.
Generated activity-check classification
The result card does not classify prose with substring or regular-expression guesses. telugu_panchangam/personal/activity_check_contract.py explicitly maps all 30 browser activities to:
- deterministic Panchangam fields;
- exact personal-rule IDs;
- exact election-chart-rule IDs; and
- every source-authored manual row's
chart,information, orpracticaldisplay section.
tools/export_activity_rules.py embeds that structured contract in src/data/activity-rules.generated.json. Freshness tests require all 113 source manual checks to have an intentional classification. They produce 114 display rows because the Gruhapravesha mixed owner/ritual sentence is deliberately split into two traceable rows rather than misclassified. This contract changes presentation only: it does not promote a manual check into an automated rule.
What remains manual
Automation is intentionally predicate-by-predicate. It does not promote a partially implemented source passage into a complete chart verdict. “Automated here” means the Drik browser post-screen. Python and MCP continue to avoid the DashaFlow service and do not claim candidate-time chart predicates passed. They do, however, apply Karnavedha's two exact day-level transition predicates before generating slots and return their criterion outcomes. Pure Python evaluators exist for other rule parity and testing, but the public Python/MCP slot orchestrator applies no other candidate-time chart evaluator.
| Activity | Automated here | Still requires practitioner or real-world review |
|---|---|---|
| Wedding | Vacant 7th; Kuja outside 8th; Shukra outside 6th | Nakshatra Pada, lineage-specific Mrityu Yoga, malefics around Lagna, Chandra association, fortification Yogas, both partners' compatibility/Tarabala/Chandrabala/Panchaka, consent |
| Annaprasana | Vacant 10th; Budha/Kuja/Shukra exclusions; Budha/Guru/Shukra-in-Lagna preference; natural-malefic-free Lagna under the named v1 convention | No residual event-chart clause after a complete, valid Drik screen; the age-month remains an information input outside this chart assessor, and baseline #284 remains open |
| Karnavedha | One Tithi and one Nakshatra throughout [local sunrise, local sunset); vacant 8th in the candidate chart | Child-age guidance, consent, sterile technique and aftercare; Python/MCP apply the day rules but do not call the candidate-chart service |
| Seemantha | Vacant 8th; Chandra outside 8th; mother's relative-star exclusions | Pregnancy month/lineage, alternative stars, Pournami dignity, medical precedence |
| Gruhapravesha | Vacant 8th; householder Janma matches | Graha strength, Upachaya/Kendra benefic-malefic judgment, Lagna ownership, Navamsa exception, ritual preparation and pregnancy safety |
| Land purchase | Guru and Kuja placements listed above | Weekday lord in Lagna, Lagna/7th-lord harmony, 11th lord in 12th, legal/title/soil/finance checks |
| Completed-house purchase | Kuja outside Lagna | Malefics outside 7th, title, inspection, affordability and contract advice |
| General purchase | Chandra and Shukra in Lagna preferences | Malefics outside 8th/12th, benefics in 2nd/10th/11th, buyer/seller scope and object-specific election |
| Entering service | Surya or Kuja in 10th/11th | Benefic in Lagna, employer/employee Yoni and Rashi-lord compatibility, employment terms and safety |
| Shantika / Paushtika | Three named placements | Combustion/omen judgment, remedial-urgency exception and ritual scope |
| Pilgrimage | Guru in Lagna/9th preference | No additional chart clause in the cited pilgrimage paragraph; travel safety and planning remain non-astrological |
| Travel | Kuja outside 8th; primary-traveller Lagna rules | General fortification, whether Guru/Shukra is well placed in Lagna, waxing-Chandra and 7th-house malefic judgment, unresolved published-rule conflicts, travel safety |
| Surgery | Vacant 8th; Chandra outside patient's Janma Rashi | Operated-body-part Rashi/house, malefic affliction, Mangala strength, Mangala-Shani aspects; clinician instructions always prevail |
| Gold / jewelry | Surya and Chandra well-placement qualifications; one full classical Graha Drishti to each luminary | No remainder for these four event-specific Gold v1 clauses after a complete, valid Drik screen; the separate general election-chart baseline is not assessed, and financial, authenticity and safety checks remain real-world responsibilities |
| Aksharabhyasa | Vacant 8th; Budha, Shukra and Guru all in the 9th as one preference | No Chapter VIII event-clause remainder after an exact screen. The overall result remains partial/provisional because the shared general baseline is not yet complete. The owner-approved project convention makes the vacancy reject win; the trio never changes score or tier. |
The Gold and Aksharabhyasa rows are conditional on a successful Drik browser screen. Non-Drik, unavailable and Python/MCP fallbacks retain the original full chart-check disclosure because they did not run these assessors. Their Panchangam inputs also remain separately disclosed project heuristics; completing the chart clause does not promote those inputs into Raman-sourced rules. “Gold event-specific chart clauses resolved” is therefore the strongest accurate UI claim: it refers only to the four disclosed Gold v1 rules, not completion of the general baseline tracked in #284 or a complete election judgment.
The Annaprasana row has the same release boundary. Non-Drik, unavailable and Python/MCP paths retain the three broad chart-guidance rows because they did not run the exact assessor. A successful, unbounded Drik result suppresses those fallback rows and may say only “Annaprasana event-specific chart assessment complete.” It always states that the general baseline in #284 remains open. The positive Lagna clause is a preference, so its resolved absence is not a failure or a reason for practitioner review.
Outside the named Gold v1 placement, Navamsa and full-aspect conventions, “aspect,” “strong,” “benefic,” “malefic,” “afflicted,” “dignified,” house-lord friendship and compatibility are not reduced to guesses. They remain manual until a named source and deterministic convention define every required choice.
Source-claim crosswalk
The complete machine-readable crosswalk is published as Muhurtam rule crosswalk JSON. It contains all 328 configured prerequisite rows across the 30 browser activities: 177 Panchangam predicates, five personal predicates, 32 election-chart predicates and 114 manual display rows. The original Gold row, three Annaprasana rows and the Karnavedha vacant-eighth row remain in this exhaustive source inventory because non-Drik, unavailable and Python/MCP fallbacks still disclose them; the successful Drik result uses the empty clause-level remainder instead. A separate expert_scope in the same artefact covers all 23 rows for the five canonical Python/MCP-only profiles: 13 deterministic predicates and 10 manual rows. Thus every prerequisite in all 35 canonical activity profiles is accounted for without pretending the five expert profiles are available in the browser.
Every row records its exact configured inputs, predicate class, criterion claim and locator, authority state, implementation status, ranking effect, and the reason it is automated or left manual. Criterion authority is classified field by field: among browser Panchangam rows, 108 use the activity's direct source claim, eight use the separately verified Sankramana claim, and 61 are explicitly labeled project heuristics. Numeric weights, tie-break ordering and review-tier caps carry a separate project-policy claim even when the preferred criterion itself is source-backed. Practical safety/routing rows and lineage conflict rows likewise do not inherit the activity's textual authority. The generated-file freshness and exhaustive-classification tests fail if a canonical rule changes without a matching crosswalk update.
The rule table stores canonical claim IDs, not bare book names. The claim's exact scope and review state live in provenance.json; the activity page gives the readable criterion-by-criterion audit.
| Claim(s) used by chart or personal screening | Registered locator | Detailed audit |
|---|---|---|
muhurta.wedding | B. V. Raman, Muhurtha, Chapter IX, Chistabo derivative internal printed pp. 41–42 (physical PDF pp. 45–46) | Wedding |
muhurta.annaprasana; muhurta.annaprasana.raman_transcription_chart | B. V. Raman, Muhurtha, Chapter VIII, inspected in the 2020 Chistabo derivative: profile on internal printed pp. 22–23 (physical PDF pp. 25–26), with all six chart clauses on internal printed p. 22 (physical PDF p. 25) | Annaprasana |
muhurta.annaprasana.source_divergence | Kalaprakasika Chapter III, printed p. 34; Muhurta Chintamani verse 18, printed p. 178 with commentary printed p. 180 | Annaprasana |
election_chart.annaprasana.raman_transcription_policy_v1 | Project policy annaprasana-raman-transcription-v1; depends on the separately registered chart and divergence claims rather than carrying direct source IDs | Annaprasana |
election_chart.natural_malefics.bphs_3_11_modern_witness; Annaprasana product-convention claims | BPHS 3.11 modern web witness; exact project-policy locators in provenance.json | Annaprasana |
muhurta.karnavedha; election_day.karnavedha_daylight_policy_v1 | B. V. Raman, Chapter VIII, inspected in the 2020 Chistabo derivative at internal printed p. 23 (physical PDF p. 26), with Chapter V at internal printed p. 12 (physical PDF p. 15); named half-open daylight interpretation policy | Karnavedha |
muhurta.seemantha | Raman, Chapter VII–VIII transition, Chistabo derivative internal printed pp. 21–22 (physical PDF pp. 24–25) | Seemantha |
muhurta.gruhapravesha | Raman, Chapter XII, Chistabo derivative internal printed pp. 52–54 (physical PDF pp. 56–58) | Gruhapravesha |
muhurta.land_purchase.building | Raman, Chapter XII, Chistabo derivative internal printed p. 54 (physical PDF p. 58) | Land purchase |
muhurta.house_purchase.completed | Raman, Chapter XII, Chistabo derivative internal printed p. 54 (physical PDF p. 58) | Completed-house purchase |
muhurta.gold_jewelry.purchase | Raman, Chapter X, Chistabo derivative internal printed p. 45 (physical PDF p. 49) | Gold / Jewelry |
election_chart.well_placed.phaladeepika_2_36; election_chart.dignity.phaladeepika_1_6; election_chart.relationships.phaladeepika_2_21_22 | Phaladeepika II.36, I.6 and II.21–22 in the registered 1950 second edition | Gold / Jewelry |
election_chart.full_graha_drishti.phaladeepika_2_23 | Phaladeepika II.23, book p. 18 (scan p. 55) | Gold / Jewelry |
election_chart.navamsa.bphs_6_12 | Brihat Parashara Hora Shastra, Chapter 6, verse 12 | Gold / Jewelry |
election_chart.chandra_solar_clearance_policy_v1; election_chart.gold_qualification_policy_v1 | Solar clearance: Surya-Siddhanta X.1, printed p. 262 (scan p. 315), as historical rationale for an explicit approximation; qualification: named Gold v1 product policy | Gold / Jewelry |
muhurta.purchase.general | Rama Daivajna, Muhurta Chintamani, verses 16–17, printed pp. 33–35 (OCR lines 2336–2374) | General purchase |
muhurta.service_entry | Muhurta Chintamani, verse 26, printed p. 38 (OCR lines 2565–2577) | Entering service |
muhurta.shantika_paushtika | Muhurta Chintamani, verse 34, printed pp. 42–43 (OCR lines 2749–2772) | Shantika / Paushtika |
muhurta.pilgrimage | Raman, Chapter XIV, Chistabo derivative internal printed pp. 60–62 (physical PDF pp. 64–66) | Pilgrimage |
muhurta.travel | Raman, Chapter XIV, Chistabo derivative internal printed pp. 60–61 (physical PDF pp. 64–65) | Travel |
muhurta.surgery | Raman, Chapter XV, Chistabo derivative internal printed pp. 64–65 (physical PDF pp. 68–69) | Surgery |
The principal registered source artifacts used on this page include the inspected 2020 Chistabo re-edit of B. V. Raman's Muhurtha, the Internet Archive Muhurta Chintamani scan, the 1945 Nirnaya Sagar Muhurta Chintamani scan, Phaladeepika, V. Subrahmanya Sastri's 1950 second edition, the BPHS 6.12 text and translation, and the Surya-Siddhanta 1935 translation. The Raman file is a modern re-edited transcription, not the bibliographically distinct UBS print edition. Annaprasana's named disagreement witness is the 1945 fifth-edition Nirnaya Sagar Press Muhurta Chintamani with commentary; other rule profiles still use the separately registered undated scan. The Phaladeepika and BPHS passages supply disclosed interpretation methods for Gold v1; they are not presented as the event-specific jewelry source.
Implementation ownership and tests
| Layer | Implementation | Contract tests |
|---|---|---|
| Canonical deterministic predicates, complete-assessor declaration, claim-specific source locators and clause-level manual remainders | telugu_panchangam/personal/election_chart_rules.py | tests/test_election_chart_screening.py; tests/test_vidyarambha_election_assessor.py; src/scorer/__tests__/election-chart-screening.test.ts |
| Versioned interpretation conventions, event admission, chart geometry, and graha-nature predicates | telugu_panchangam/personal/election_assessors/event_admission.py; chart_geometry.py; graha_nature.py; mirrored modules under src/scorer/election-assessors/ | Synthetic Gold predicate oracle plus frozen actual public-gateway outcome cells across Hyderabad and Sydney, two dates, and pass/fail/unknown/conflict/boundary dispositions; Python/TypeScript parity and compatibility-boundary cases in the election-chart screening suites |
| Complete activity-by-prerequisite source crosswalk | tools/export_muhurtam_rule_crosswalk.py; docs/reference/muhurtam-rule-crosswalk.json | tests/test_muhurtam_rule_crosswalk.py; exporter --check; documentation output digest check |
| Structured all-activity check classification | telugu_panchangam/personal/activity_check_contract.py; tools/export_activity_rules.py; src/data/activity-rules.generated.json | tests/test_activity_check_contract.py; src/scorer/__tests__/activity-check-contract.test.ts |
| Pure Python snapshot/window evaluator | telugu_panchangam/personal/election_chart.py | tests/test_election_chart_screening.py; shared Aksharabhyasa oracle and projection replay |
| Pure Python personal-role contract | telugu_panchangam/personal/personal_election.py | tests/test_personal_election_parity.py; tests/fixtures/personal-election-parity.json |
| Generated browser rule contract | tools/export_election_chart_rules.py; src/data/election-chart-rules.generated.json | exporter --check; Python/TypeScript parity behavior |
| Strict browser API adapter | src/lib/election-chart-api.ts | src/__tests__/election-chart-api.test.ts |
| TypeScript predicate mirror | src/scorer/election-chart-screening.ts | src/scorer/__tests__/election-chart-screening.test.ts; src/scorer/__tests__/election-chart-vidyarambha-projection.test.ts |
| Personal-role precedence | src/scorer/personal-election-screening.ts | src/scorer/__tests__/personal-election-screening.test.ts |
| Bounded post-ranking enrichment | src/scorer/election-chart-enrichment.ts | src/scorer/__tests__/election-chart-enrichment.test.ts |
| Local Lagna frame and transition-guard envelope | tools/audit_lagna_boundary_guard.py; tests/fixtures/lagna-boundary-guard-audit.json | tests/test_lagna_boundary_guard_audit.py; full report comparison runs in the default Python suite |
| City projection | src/data/cities.ts | tests/test_city_browser_projection.py |
| Browser journey and disclosure | src/panels/tarabalam.ts | src/__tests__/muhurta-profile-panel.test.ts plus browser journey verification |
| Public stateless gateway | astro-unified-core guest route | Contract, CORS, body-cap, rate-limit and redaction tests in that repository |
| Authenticated chart projection | dashaflow-sidecar election-chart route | Validation, order, nine-graha, 2/24-chart, streamed-body, three interior Drik Panchang comparisons and two negative boundary-equivalence fixtures in that repository |
Independent release review found that the original sidecar mock success fixtures did not satisfy the browser's node/opposition and related cross-field invariants. The remediation began at candidate 97eece13, merged through DashaFlow PR #1, and is present in the exact released production revision c84fd856. On 2026-09-04, that revision served an authenticated synthetic election-chart derivation through Astro production revision 4106f097 with HTTP 200. Producer story #443 is closed and Done. The browser validator remains strict; release of the producer fix is evidence for keeping, not relaxing, those invariants.
The Python table is the source of truth for the 32 chart predicates. The Python personal module and TypeScript mirror carry the same five personal rule IDs, effects, locators, input evidence and all-sampled-state result semantics, with fixture parity tests. The TypeScript chart evaluator is a browser mirror and must never acquire an unexported rule. The sidecar supplies positional facts only; it does not decide which activity is auspicious.
Gold's two test fixtures have intentionally different evidentiary roles. tests/fixtures/election_chart_gold_oracle.json is synthetic and isolates predicate transitions. tests/fixtures/election_chart_gold_gateway_oracle.json freezes unedited HTTP 200 cells produced by Astro revision 4106f09708a154f1c2401880ebe8f9c0b9162eb5 and DashaFlow revision c84fd856b17120c80e1bb7e455246a0ec8e429ea. The actual gateway cells cover Hyderabad and Sydney on two dates and collectively yield pass, fail, unknown, conflict and boundary Gold outcomes. Tests first verify all nine unique grahas and recomputed Whole Sign houses, then require identical Python and TypeScript outcomes. These cells prove compatibility with the deployed deterministic calculation contract; the separate six-instant Drik comparison above remains the external ephemeris evidence.
UI review evidence
The Karnavedha review-evidence directory at docs/screenshots/karnavedha-assessor-2026-09-04/ contains twelve deterministic images: pass, Tithi fail, Nakshatra fail, both fail and minute-precision unknown at 1440×900 and 390×844, plus a chart-component pass crop rendered at each viewport that visibly records 8th house is vacant. Its manifest records each expected state/copy, frame purpose, capture kind, image size and digest. The failure cases prove that no chart request is made for a rejected day; the pass overview expands both daylight outcomes and the two additional crops preserve the candidate-chart result. Recreate it with:
python tools/capture_karnavedha_assessor_screenshots.py --dist distThe Aksharabhyasa review-evidence directory at docs/screenshots/aksharabhyasa-chart-assessor-2026-09-05/ contains ten owner-accepted captures: selector, pass, preference miss, hard rejection and unknown states at 1440×900 and 390×844. The manifest pins the activity, expected copy, viewport and SHA-256 for every image. These fixtures preserve the scoped partial/provisional wording and exercise the built application without a live service.
The Gold review-evidence directory at docs/screenshots/gold-chart-screening-2026-09-04/ contains a reproducible 15-image fixture matrix. Six fresh Gold images cover pass, conclusive condition miss with rating cap, and fail-closed unknown at both 1440×900 and 390×844. The remaining images preserve generic positive, mixed, mandatory failure, unsupported-system, offline, malformed-response, loading, and 20-second timeout states. Its fixture-manifest.json records the exact scenario, activity, system, viewport, expected state/copy, and SHA-256 for every image. Fixture captures exercise the built application without calling a live service.
The successor directory at docs/screenshots/annaprasana-chart-assessor-2026-09-04/ contains eight content-distinct captures for complete pass, resolved preference miss, mandatory removal with observed evidence, and phase-boundary unknown at both 1440×900 and 390×844. Its own manifest and evidence test bind every image to the named scenario, viewport, expected copy, and checksum.
The earlier muhurtam-chart-screening-2026-08-29/ directory remains as an immutable historical record. Its Gold manual-only image predates this assessor and is not evidence for the current runtime state.
Recreate that matrix from a local production build:
python tools/capture_muhurta_chart_screenshots.py --dist dist
python tools/capture_muhurta_chart_screenshots.py \
--dist dist --annaprasana-onlyReproduce and verify
From this repository root:
NUMBA_CACHE_DIR=/private/tmp/telugu-numba-cache \
.venv/bin/python -m pytest \
tests/test_election_chart_screening.py \
tests/test_personal_election_parity.py \
tests/test_activity_check_contract.py \
tests/test_city_browser_projection.py \
tests/test_lagna_boundary_guard_audit.py -q
npm test -- \
src/__tests__/election-chart-api.test.ts \
src/scorer/__tests__/election-chart-screening.test.ts \
src/scorer/__tests__/personal-election-screening.test.ts \
src/scorer/__tests__/election-chart-enrichment.test.ts \
src/scorer/__tests__/activity-check-contract.test.ts \
src/__tests__/muhurta-profile-panel.test.ts
npm run activity:check
npm run typecheck
npm run build:docs
npm run docs:check-outputThen run the complete offline repository contract before commit:
NUMBA_CACHE_DIR=/private/tmp/telugu-numba-cache \
.venv/bin/python tools/verify_project.pyFor a manual local check, select Drik, an activity with an automated rule, a city, and any required primary role. Confirm that the result summary names chart screening, failed reject rules do not appear as retained cards, computed passes and unknowns are visible, and remaining qualitative checks still say they need practitioner review. Then select Gold with Drik and confirm that the chart route runs, all four named qualification outcomes and their observed evidence are visible, and a complete result has no duplicate practitioner chart remainder. A resolved qualification failure must retain the slot, cap an otherwise Excellent tier to Good, keep the raw score unchanged, and say that the event-specific condition was conclusively not met without asking for practitioner review. An unknown must be labelled indeterminate at a calculation boundary or missing fact and remain review-gated. If one retained slot has both dispositions, the summary must report that it appears in both counts. Finally repeat Gold with a non-Drik system: it must not call the chart route or claim that Gold v1 ran, and it must retain the honest fallback chart-check disclosure.
Review this page and the machine-readable computation record whenever the contract version, ayanamsha, house system, node choice, canonical graha set, source claim, predicate effect, role precedence, boundary sampling, batch size, ranking order, gateway privacy contract or fallback behavior changes.