Files
Jyotisha/docs/superpowers/plans/2026-06-30-top-reader-adjudication.md
T
2026-07-08 17:03:04 +08:00

21 KiB

Top Reader Adjudication Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Upgrade the default career, relationship, and finance reading workflows to use a shared top-reader-style adjudication skeleton with multi-reference summaries and selected modifier bridges, while reusing existing strict workflow code and minimizing extra compute.

Architecture: Reuse the current strict workflow builders in mcp_server.py as the primary evidence source, normalize them through a shared adjudication helper, and surface the reshaped contract through jyotish_engine.py, jyotish_api_server.py, and the existing prompt-pack/frontend consumer layers. Do not introduce a second engine or a full 641-callable VedAstro execution path; instead, reshape current evidence into a common four-stage contract plus a lightweight multi_reference_reading_summary.

Tech Stack: Python, existing strict workflow collectors, pytest, existing frontend productization tests, existing prompt-pack evidence snapshot contract.

Global Constraints

  • Reuse current strict workflow collectors before adding new collectors.
  • Reuse existing bridge helpers before creating new scoring paths.
  • Reuse current full-reading/module outputs by reference where possible.
  • Do not add all-method VedAstro execution to the default path.
  • Prefer small contract reshaping over new compute-heavy logic.
  • Keep official calls cached and reused; do not add new heavyweight request fans.
  • Preserve the existing honesty boundaries: emit blocked, conflicts, and confidence_cap instead of smoothing over missing layers.
  • Keep career, relationship, and finance domain-specific evidence requirements intact while sharing structure.

Task 1: Add the shared adjudication contract builder in mcp_server.py

Files:

  • Modify: <repo>/mcp_server.py
  • Test: <repo>/tests/test_mcp_strict_workflow_career.py
  • Test: <repo>/tests/test_mcp_strict_workflow_relationship.py
  • Test: <repo>/tests/test_mcp_strict_workflow_finance.py

Interfaces:

  • Consumes:

    • existing strict route present_evidence
    • existing event_judgement
    • existing official_primary_evidence
    • existing local_supplemental_evidence
    • existing conflicts
    • existing confidence_cap
  • Produces:

    • _build_adjudication_stages(route: str, present: Dict[str, Any], event_judgement: Dict[str, Any]) -> Dict[str, Any]
    • _build_multi_reference_reading_summary(route: str, present: Dict[str, Any], strict: Dict[str, Any]) -> Dict[str, Any]
    • strict contract keys:
      • adjudication_stages
      • multi_reference_reading_summary
      • verdict
      • dominant_label
      • main_conflicts
  • Step 1: Write the failing tests

Add assertions to each strict workflow domain test file for the new shared fields:

def test_career_strict_contract_exposes_adjudication_stages() -> None:
    result = mcp_server._collect_strict_evidence("career", modules)
    assert result["adjudication_stages"]["promise"]["status"] in {"present", "weak", "missing"}
    assert result["adjudication_stages"]["activation"]["required_timing_systems"] == ["Vimshottari", "Narayana"]
    assert "multi_reference_reading_summary" in result
    assert "root_frame" in result["multi_reference_reading_summary"]

Repeat the same shape expectation for relationship and finance, adapted to each route.

  • Step 2: Run tests to verify they fail

Run:

python3 -m pytest tests/test_mcp_strict_workflow_career.py tests/test_mcp_strict_workflow_relationship.py tests/test_mcp_strict_workflow_finance.py -k "adjudication_stages or multi_reference_reading_summary" -q

Expected: FAIL with missing strict contract keys such as adjudication_stages or multi_reference_reading_summary.

  • Step 3: Write the minimal implementation

Implement shared helpers near the existing strict helper section in mcp_server.py:

def _build_adjudication_stages(route: str, present: Dict[str, Any], event_judgement: Dict[str, Any]) -> Dict[str, Any]:
    dominant_label = event_judgement.get("dominant_label")
    return {
        "promise": {
            "status": "present" if _has_promise_evidence(route, present) else "weak",
            "drivers": _promise_drivers(route, present),
        },
        "activation": {
            "status": "present" if _has_activation_evidence(route, present) else "weak",
            "required_timing_systems": ["Vimshottari", "Narayana"],
            "drivers": _activation_drivers(route, present),
        },
        "manifestation": {
            "status": "present" if dominant_label else "weak",
            "drivers": event_judgement.get("secondary_context") or [],
        },
        "label": {
            "status": "present" if dominant_label else "missing",
            "value": dominant_label,
            "verdict": event_judgement.get("verdict"),
        },
    }

Also add a small route-aware summary builder:

def _build_multi_reference_reading_summary(route: str, present: Dict[str, Any], strict: Dict[str, Any]) -> Dict[str, Any]:
    return {
        "root_frame": _summary_root_frame(route, present),
        "divisional_frame": _summary_divisional_frame(route, present),
        "visibility_frame": _summary_visibility_frame(route, present),
        "karaka_frame": _summary_karaka_frame(route, present),
        "timing_frame": _summary_timing_frame(route, present),
        "modifier_frame": _summary_modifier_frame(route, present),
        "conflict_frame": {
            "conflicts": strict.get("conflicts") or [],
            "confidence_cap": strict.get("confidence_cap"),
        },
    }

Attach these fields inside each strict route result, reusing the current per-route present and event_judgement.

  • Step 4: Run tests to verify they pass

Run:

python3 -m pytest tests/test_mcp_strict_workflow_career.py tests/test_mcp_strict_workflow_relationship.py tests/test_mcp_strict_workflow_finance.py -k "adjudication_stages or multi_reference_reading_summary" -q

Expected: PASS

  • Step 5: Commit
git add mcp_server.py tests/test_mcp_strict_workflow_career.py tests/test_mcp_strict_workflow_relationship.py tests/test_mcp_strict_workflow_finance.py
git commit -m "feat: add shared top-reader adjudication contract"

Task 2: Promote selected bridge layers into the shared modifier frame

Files:

  • Modify: <repo>/mcp_server.py
  • Test: <repo>/tests/test_mcp_strict_workflow_finance.py
  • Test: <repo>/tests/test_mcp_strict_workflow_relationship.py
  • Test: <repo>/tests/test_mcp_strict_workflow_functional_layer.py

Interfaces:

  • Consumes:

    • present["functional_benefic_malefic"]
    • present["ashtakavarga_finance_support"]
    • present["wealth_promise_strength"]
    • marriage route evidence already emitted into present
    • yogi_active in finance event_judgement.secondary_context
  • Produces:

    • multi_reference_reading_summary["modifier_frame"]
    • adjudication_stages["manifestation"]["bridge_modifiers"]
  • Step 1: Write the failing tests

Add focused bridge promotion assertions:

def test_finance_summary_modifier_frame_includes_yogi_and_ashtakavarga_only_as_modifiers() -> None:
    strict = mcp_server._collect_strict_evidence("finance", modules)
    modifier = strict["multi_reference_reading_summary"]["modifier_frame"]
    assert "functional_benefic_malefic" in modifier
    assert modifier["ashtakavarga_finance_support"]["source"] == "ashtakavarga_house_scores_bridge_v1"
    assert modifier["yogi_support"]["role"] == "modifier_only"
def test_relationship_summary_modifier_frame_surfaces_label_lift_related_modifiers() -> None:
    strict = mcp_server._collect_strict_evidence("relationship", modules)
    modifier = strict["multi_reference_reading_summary"]["modifier_frame"]
    assert "functional_benefic_malefic" in modifier
    assert "manifestation_split" in modifier
  • Step 2: Run tests to verify they fail

Run:

python3 -m pytest tests/test_mcp_strict_workflow_finance.py tests/test_mcp_strict_workflow_relationship.py tests/test_mcp_strict_workflow_functional_layer.py -k "modifier_frame or yogi or manifestation_split" -q

Expected: FAIL with missing modifier-frame keys.

  • Step 3: Write the minimal implementation

Extend the summary helpers in mcp_server.py:

def _summary_modifier_frame(route: str, present: Dict[str, Any]) -> Dict[str, Any]:
    frame = {
        "functional_benefic_malefic": present.get("functional_benefic_malefic"),
        "shadbala": present.get("shadbala"),
        "argala_support": present.get("argala_support"),
    }
    if route == "finance":
        frame["ashtakavarga_finance_support"] = present.get("ashtakavarga_finance_support")
        frame["yogi_support"] = {
            "role": "modifier_only",
            "value": present.get("wealth_promise_strength"),
        }
    if route == "relationship":
        frame["manifestation_split"] = {
            "role": "modifier_only",
            "signals": [
                "relationship_formation",
                "legal_marriage",
                "public_formalization",
            ],
        }
    return frame

Do not create new calculators here; only repackage current evidence and known route-specific bridge metadata.

  • Step 4: Run tests to verify they pass

Run:

python3 -m pytest tests/test_mcp_strict_workflow_finance.py tests/test_mcp_strict_workflow_relationship.py tests/test_mcp_strict_workflow_functional_layer.py -k "modifier_frame or yogi or manifestation_split" -q

Expected: PASS

  • Step 5: Commit
git add mcp_server.py tests/test_mcp_strict_workflow_finance.py tests/test_mcp_strict_workflow_relationship.py tests/test_mcp_strict_workflow_functional_layer.py
git commit -m "feat: promote selected bridge layers into shared modifiers"

Task 3: Compact and expose the new contract through jyotish_engine.py

Files:

  • Modify: <repo>/scripts/jyotish_engine.py
  • Test: <repo>/tests/test_cli_smoke.py
  • Test: <repo>/tests/test_vedastro_official_full_snapshot.py

Interfaces:

  • Consumes:

    • strict workflow contracts embedded in modules
  • Produces:

    • _compact_strict_workflow_contract(strict: Dict[str, Any]) -> Dict[str, Any]
    • ai_prompt_pack["evidence_snapshot"]["strict_workflow_contracts"][route]["adjudication_stages"]
    • ai_prompt_pack["evidence_snapshot"]["strict_workflow_contracts"][route]["multi_reference_reading_summary"]
  • Step 1: Write the failing tests

Add prompt-pack expectations:

def test_full_reading_prompt_pack_carries_adjudication_stages_and_multi_reference_summary() -> None:
    result = run_full_reading(...)
    strict = result["ai_prompt_pack"]["evidence_snapshot"]["strict_workflow_contracts"]["career"]
    assert "adjudication_stages" in strict
    assert "multi_reference_reading_summary" in strict
    assert "modifier_frame" in strict["multi_reference_reading_summary"]
  • Step 2: Run tests to verify they fail

Run:

python3 -m pytest tests/test_cli_smoke.py tests/test_vedastro_official_full_snapshot.py -k "adjudication_stages or multi_reference_reading_summary" -q

Expected: FAIL with missing keys in compact strict workflow contract or evidence snapshot.

  • Step 3: Write the minimal implementation

Extend the strict contract compactor in scripts/jyotish_engine.py:

def _compact_strict_workflow_contract(strict):
    return {
        "confidence_cap": strict.get("confidence_cap"),
        "blocked": strict.get("blocked"),
        "blocked_items": strict.get("blocked_items") or [],
        "conflicts": strict.get("conflicts") or [],
        "official_primary_evidence": strict.get("official_primary_evidence") or {},
        "local_supplemental_evidence": strict.get("local_supplemental_evidence") or {},
        "adjudication_stages": strict.get("adjudication_stages") or {},
        "multi_reference_reading_summary": strict.get("multi_reference_reading_summary") or {},
        "verdict": strict.get("verdict"),
        "dominant_label": strict.get("dominant_label"),
        "main_conflicts": strict.get("main_conflicts") or [],
    }

Also ensure the prompt-pack evidence snapshot reuses this compacted form instead of recomputing anything heavy.

  • Step 4: Run tests to verify they pass

Run:

python3 -m pytest tests/test_cli_smoke.py tests/test_vedastro_official_full_snapshot.py -k "adjudication_stages or multi_reference_reading_summary" -q

Expected: PASS

  • Step 5: Commit
git add scripts/jyotish_engine.py tests/test_cli_smoke.py tests/test_vedastro_official_full_snapshot.py
git commit -m "feat: expose top-reader contract in prompt pack"

Task 4: Surface the reshaped contract in API outputs with no extra heavy recompute

Files:

  • Modify: <repo>/scripts/jyotish_api_server.py
  • Test: <repo>/tests/test_api_server_security.py
  • Test: <repo>/tests/test_historical_event_backtest.py

Interfaces:

  • Consumes:

    • prompt-pack evidence_snapshot
    • existing consultation workflow contract
    • strict workflow contract summary
  • Produces:

    • consultation/high-rigor API outputs that include:
      • adjudication_stages
      • multi_reference_reading_summary
      • verdict
      • dominant_label
      • main_conflicts
  • Step 1: Write the failing tests

Add API-level shape assertions:

def test_consultation_workflow_passes_through_top_reader_contract(monkeypatch) -> None:
    result = handler._compute_consultation_workflow(payload)
    guided = result["guided_topics"][0]
    assert "adjudication_stages" in guided
    assert "multi_reference_reading_summary" in guided
def test_high_rigor_summary_passes_through_multi_reference_summary(monkeypatch) -> None:
    summary = handler._high_rigor_vedastro_official_summary(prompt_official, range_scan, range_metadata)
    assert "multi_reference_reading_summary" in summary
  • Step 2: Run tests to verify they fail

Run:

python3 -m pytest tests/test_api_server_security.py tests/test_historical_event_backtest.py -k "top_reader_contract or multi_reference_reading_summary" -q

Expected: FAIL with missing API passthrough keys.

  • Step 3: Write the minimal implementation

Update scripts/jyotish_api_server.py to reuse existing prompt-pack or strict contract nodes:

strict_contract = prompt_official.get("strict_workflow_contracts", {}).get(route_key, {})
summary["adjudication_stages"] = strict_contract.get("adjudication_stages") or {}
summary["multi_reference_reading_summary"] = strict_contract.get("multi_reference_reading_summary") or {}
summary["verdict"] = strict_contract.get("verdict")
summary["dominant_label"] = strict_contract.get("dominant_label")
summary["main_conflicts"] = strict_contract.get("main_conflicts") or strict_contract.get("conflicts") or []

Where guided topic objects are built, attach the same already-computed contract by reference or compact copy; do not call full-reading again.

  • Step 4: Run tests to verify they pass

Run:

python3 -m pytest tests/test_api_server_security.py tests/test_historical_event_backtest.py -k "top_reader_contract or multi_reference_reading_summary" -q

Expected: PASS

  • Step 5: Commit
git add scripts/jyotish_api_server.py tests/test_api_server_security.py tests/test_historical_event_backtest.py
git commit -m "feat: surface top-reader adjudication contract in api outputs"

Task 5: Keep the frontend and user-facing surfaces simple while consuming the richer contract

Files:

  • Modify: <repo>/jyotish-app/main.js
  • Modify: <repo>/jyotish-app/ai-chat.js
  • Test: <repo>/tests/test_frontend_productization.py

Interfaces:

  • Consumes:

    • consultation workflow output
    • prompt-pack evidence snapshot
    • compact strict contract
  • Produces:

    • visible simple user summaries
    • AI chat context that includes the new top-reader contract
  • Step 1: Write the failing tests

Add frontend token tests:

def test_ai_chat_and_complete_reading_surface_top_reader_contract_tokens() -> None:
    main = read_main_js()
    ai_chat = read_ai_chat_js()
    assert "multi_reference_reading_summary" in main
    assert "adjudication_stages" in main
    assert "multi_reference_reading_summary" in ai_chat
    assert "adjudication_stages" in ai_chat

Also add one test that the UI still prefers compact summaries rather than dumping raw full evidence.

  • Step 2: Run tests to verify they fail

Run:

python3 -m pytest tests/test_frontend_productization.py -k "top_reader_contract or multi_reference_reading_summary or adjudication_stages" -q

Expected: FAIL with missing frontend references to the new contract.

  • Step 3: Write the minimal implementation

Update frontend readers to expose only compact user-facing summaries and AI context:

const topReaderContract = chartData?.ai_prompt_pack?.evidence_snapshot?.strict_workflow_contracts?.[routeKey] || {};
const adjudicationStages = topReaderContract.adjudication_stages || {};
const multiReferenceSummary = topReaderContract.multi_reference_reading_summary || {};

Use these to:

  • show a compact “how this conclusion was formed” section

  • append structured context to AI chat

  • avoid rendering the full raw evidence tree unless already needed in an audit panel

  • Step 4: Run tests to verify they pass

Run:

python3 -m pytest tests/test_frontend_productization.py -k "top_reader_contract or multi_reference_reading_summary or adjudication_stages" -q

Expected: PASS

  • Step 5: Commit
git add jyotish-app/main.js jyotish-app/ai-chat.js tests/test_frontend_productization.py
git commit -m "feat: consume top-reader adjudication contract in frontend"

Task 6: Run the focused regression bundle and then the broader verification pass

Files:

  • Modify: <repo>/progress.md

Interfaces:

  • Consumes:

    • all modified code from Tasks 1-5
  • Produces:

    • recorded verification summary in progress.md
  • Step 1: Run the focused contract regressions

Run:

python3 -m pytest \
  tests/test_mcp_strict_workflow_career.py \
  tests/test_mcp_strict_workflow_relationship.py \
  tests/test_mcp_strict_workflow_finance.py \
  tests/test_mcp_strict_workflow_functional_layer.py \
  tests/test_cli_smoke.py \
  tests/test_vedastro_official_full_snapshot.py \
  tests/test_api_server_security.py \
  tests/test_historical_event_backtest.py \
  tests/test_frontend_productization.py \
  -k "adjudication_stages or multi_reference_reading_summary or top_reader_contract or modifier_frame" -q

Expected: PASS

  • Step 2: Run the broader targeted verification

Run:

python3 -m pytest tests/test_mcp_strict_workflow_career.py tests/test_mcp_strict_workflow_relationship.py tests/test_mcp_strict_workflow_finance.py tests/test_api_server_security.py tests/test_cli_smoke.py tests/test_frontend_productization.py -q

Expected: PASS

  • Step 3: Update progress.md with the landed contract and verification notes

Add an entry similar to:

- 2026-06-30 Top-reader adjudication contract landed:
  - shared `promise -> activation -> manifestation -> label`
  - `multi_reference_reading_summary`
  - bridge promotion kept modifier-only
  - prompt-pack/API/frontend all consume the same compact contract
  - focused and targeted regressions passed
  • Step 4: Run diff hygiene checks

Run:

git diff --check

Expected: no output

  • Step 5: Commit
git add progress.md
git commit -m "docs: record top-reader adjudication verification"

Self-Review

Spec coverage

  • Shared four-stage skeleton: covered by Task 1
  • Multi-reference summary: covered by Tasks 1, 3, 4, and 5
  • Selected bridge promotion: covered by Task 2
  • Prompt-pack/API/frontend consumption: covered by Tasks 3, 4, and 5
  • Compute minimization and reuse constraints: enforced in every task through existing-contract reuse and no new engine work

Placeholder scan

  • No TODO, TBD, or “implement later” placeholders remain.
  • Each task includes exact files, exact commands, and exact expected behavior.

Type consistency

  • adjudication_stages and multi_reference_reading_summary are introduced first in mcp_server.py, then compacted in jyotish_engine.py, then consumed in jyotish_api_server.py and frontend.
  • verdict, dominant_label, and main_conflicts are named consistently across all tasks.

Execution Handoff

Plan complete and saved to docs/superpowers/plans/2026-06-30-top-reader-adjudication.md. Two execution options:

1. Subagent-Driven (recommended) - I dispatch a fresh subagent per task, review between tasks, fast iteration

2. Inline Execution - Execute tasks in this session using executing-plans, batch execution with checkpoints

Which approach?