fix(synastry): close the second review gaps on evidence, billing, and the sidebar
The second review still failed on missing database and route coverage, an unmarked relationship structure, a stuck English lease, and a sidebar that fetched the product switch itself. Co-Authored-By: Grok (agent loop) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Grok (agent loop)
Cursor
parent
51bb3c1e7f
commit
362d903c31
@@ -96,6 +96,91 @@ def upcoming_vimshottari(reading: dict[str, Any], today: str, years: int = 5) ->
|
||||
return rows
|
||||
|
||||
|
||||
_SIGNS = (
|
||||
"Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
|
||||
"Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces",
|
||||
)
|
||||
_SIGN_LORDS = {
|
||||
"Aries": "Mars", "Taurus": "Venus", "Gemini": "Mercury", "Cancer": "Moon",
|
||||
"Leo": "Sun", "Virgo": "Mercury", "Libra": "Venus", "Scorpio": "Mars",
|
||||
"Sagittarius": "Jupiter", "Capricorn": "Saturn", "Aquarius": "Saturn", "Pisces": "Jupiter",
|
||||
}
|
||||
|
||||
|
||||
def _reading_packet(reading: dict[str, Any]) -> dict[str, Any]:
|
||||
nested = reading.get("raw_full_reading")
|
||||
return nested if isinstance(nested, dict) else reading
|
||||
|
||||
|
||||
def _sign_name(value: Any) -> str | None:
|
||||
if isinstance(value, str) and value.strip():
|
||||
return value.strip()
|
||||
if not isinstance(value, dict):
|
||||
return None
|
||||
for key in ("sign", "sign_name", "rasi"):
|
||||
sign = value.get(key)
|
||||
if isinstance(sign, str) and sign.strip():
|
||||
return sign.strip()
|
||||
for key in ("longitude", "degree_raw", "lon", "degree"):
|
||||
longitude = value.get(key)
|
||||
if isinstance(longitude, (int, float)) and not isinstance(longitude, bool):
|
||||
return _SIGNS[int(float(longitude) % 360.0) // 30]
|
||||
return None
|
||||
|
||||
|
||||
def _named_planet(root: Any, path: tuple[str, ...]) -> str | None:
|
||||
value = root
|
||||
for key in path:
|
||||
value = value.get(key) if isinstance(value, dict) else None
|
||||
if isinstance(value, str) and value.strip():
|
||||
return value.strip()
|
||||
if isinstance(value, dict):
|
||||
planet = value.get("planet") or value.get("name")
|
||||
if isinstance(planet, str) and planet.strip():
|
||||
return planet.strip()
|
||||
return None
|
||||
|
||||
|
||||
def relationship_structure(reading: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Signs and relationship points the longitude-only snapshot does not carry."""
|
||||
modules = _reading_packet(reading).get("modules")
|
||||
modules = modules if isinstance(modules, dict) else {}
|
||||
chart = modules.get("chart") if isinstance(modules.get("chart"), dict) else {}
|
||||
planets = chart.get("planets") if isinstance(chart.get("planets"), dict) else {}
|
||||
ascendant = _sign_name(chart.get("ascendant"))
|
||||
seventh = _SIGN_LORDS[_SIGNS[(_SIGNS.index(ascendant) + 6) % 12]] if ascendant in _SIGN_LORDS else None
|
||||
jaimini = modules.get("jaimini") if isinstance(modules.get("jaimini"), dict) else {}
|
||||
darakaraka = (
|
||||
_named_planet(jaimini, ("chara_karaka_standard", "karakas", "DK"))
|
||||
or _named_planet(jaimini, ("chara_karaka_8", "karaka_table_8", "Darakaraka"))
|
||||
or _named_planet(jaimini, ("chara_karaka_7", "karaka_table", "Darakaraka"))
|
||||
)
|
||||
special = modules.get("special_lagnas") if isinstance(modules.get("special_lagnas"), dict) else {}
|
||||
arudha = modules.get("arudha_padas") if isinstance(modules.get("arudha_padas"), dict) else {}
|
||||
padas = arudha.get("padas") if isinstance(arudha.get("padas"), dict) else arudha
|
||||
upapada = _sign_name(special.get("Upapada_Lagna") or special.get("UL"))
|
||||
if upapada is None and isinstance(padas, dict):
|
||||
upapada = _sign_name(padas.get("UL"))
|
||||
a7 = _sign_name(special.get("A7") or special.get("Darapada"))
|
||||
if a7 is None and isinstance(padas, dict):
|
||||
a7 = _sign_name(padas.get("A7"))
|
||||
vargas = modules.get("varga_full") if isinstance(modules.get("varga_full"), dict) else {}
|
||||
navamsa = vargas.get("D9_Navamsa") if isinstance(vargas.get("D9_Navamsa"), dict) else {}
|
||||
d9 = _sign_name(navamsa.get("Ascendant") or navamsa.get("ascendant"))
|
||||
return {
|
||||
"ascendant": {"sign": ascendant} if ascendant else {},
|
||||
"planets": {
|
||||
"Venus": {"sign": _sign_name(planets.get("Venus"))} if _sign_name(planets.get("Venus")) else {},
|
||||
"Moon": {"sign": _sign_name(planets.get("Moon"))} if _sign_name(planets.get("Moon")) else {},
|
||||
},
|
||||
"seventh_lord": seventh,
|
||||
"darakaraka": darakaraka,
|
||||
"upapada": upapada,
|
||||
"A7": a7,
|
||||
"d9": {"ascendant": d9} if d9 else {},
|
||||
}
|
||||
|
||||
|
||||
def build_synastry_full_dossier(
|
||||
handler: Any,
|
||||
person_a: dict[str, Any],
|
||||
@@ -111,6 +196,11 @@ def build_synastry_full_dossier(
|
||||
reading_a = future_a.result()
|
||||
reading_b = future_b.result()
|
||||
dossier = _dossier_builder()(reading_a, reading_b)
|
||||
if isinstance(dossier, dict):
|
||||
dossier["local_structures"] = {
|
||||
"person_a": relationship_structure(reading_a if isinstance(reading_a, dict) else {}),
|
||||
"person_b": relationship_structure(reading_b if isinstance(reading_b, dict) else {}),
|
||||
}
|
||||
today = str(person_a.get("today") or person_b.get("today") or "")
|
||||
snapshots = dossier.get("chart_snapshots") if isinstance(dossier, dict) else {}
|
||||
snapshots = snapshots if isinstance(snapshots, dict) else {}
|
||||
|
||||
@@ -36,6 +36,31 @@ SECTION_ORDER = (
|
||||
"practices",
|
||||
)
|
||||
PROSE_SECTIONS = SECTION_ORDER[:7]
|
||||
ZH_SECTION_MINIMUM = 120
|
||||
ZH_TOTAL_MINIMUM = 1800
|
||||
EN_SECTION_MINIMUM = 80
|
||||
EN_TOTAL_MINIMUM = 1100
|
||||
STATUS_ONLY_VALUES = {
|
||||
"ready_for_comparison",
|
||||
"executed",
|
||||
"present",
|
||||
"used",
|
||||
"available",
|
||||
"passed",
|
||||
"parameter_sensitive",
|
||||
"partial",
|
||||
"weak",
|
||||
"observation_only",
|
||||
"not_applicable",
|
||||
"not_used",
|
||||
"not_used_for_date_intersection",
|
||||
"blocked",
|
||||
"missing",
|
||||
"queued",
|
||||
"running",
|
||||
"ready",
|
||||
"failed",
|
||||
}
|
||||
EVIDENCE_LABELS = (
|
||||
"multi_system_consensus",
|
||||
"single_system_inference",
|
||||
@@ -148,7 +173,7 @@ def _string_values(value: Any) -> set[str]:
|
||||
found: set[str] = set()
|
||||
if isinstance(value, str):
|
||||
stripped = value.strip()
|
||||
if stripped:
|
||||
if stripped and stripped.lower() not in STATUS_ONLY_VALUES:
|
||||
found.add(stripped)
|
||||
elif isinstance(value, dict):
|
||||
for item in value.values():
|
||||
@@ -231,7 +256,7 @@ def validate_synastry_reader(
|
||||
text = str(row.get("text") or "")
|
||||
prose_characters += len(re.sub(r"\s+", "", text))
|
||||
prose_words += len(re.findall(r"\b[\w']+\b", text))
|
||||
minimum = 120 if language == "zh" else 80
|
||||
minimum = ZH_SECTION_MINIMUM if language == "zh" else EN_SECTION_MINIMUM
|
||||
measured = len(re.sub(r"\s+", "", text)) if language == "zh" else len(re.findall(r"\b[\w']+\b", text))
|
||||
if measured < minimum:
|
||||
failures.append(_fail(section_id, "too_short", str(measured)))
|
||||
@@ -290,7 +315,7 @@ def validate_synastry_reader(
|
||||
if not evidence or evidence not in practice_values:
|
||||
failures.append(_fail("practices", "evidence_missing", evidence or "item"))
|
||||
|
||||
total_minimum = 1800 if language == "zh" else 1100
|
||||
total_minimum = ZH_TOTAL_MINIMUM if language == "zh" else EN_TOTAL_MINIMUM
|
||||
total = prose_characters if language == "zh" else prose_words
|
||||
if total < total_minimum:
|
||||
failures.append(_fail("delivery", "too_short", str(total)))
|
||||
|
||||
Reference in New Issue
Block a user