Add VedAstro parity matrix
This commit is contained in:
@@ -39,8 +39,11 @@ This file is the small index for the current engineering fronts that still drive
|
||||
|
||||
## VedAstro Adapter MVP
|
||||
|
||||
- `/Users/wuyongnaren/Documents/印度占星/docs/research/vedastro_parity_matrix_latest.md`
|
||||
- `/Users/wuyongnaren/Documents/印度占星/docs/research/vedastro_parity_matrix_latest.json`
|
||||
- `/Users/wuyongnaren/Documents/印度占星/scripts/vedastro_service_adapter.py`
|
||||
- follow only after the Jaimini marriage bridge v1 regression loop is closed
|
||||
- Use the parity matrix before adding or claiming VedAstro-equivalent capability.
|
||||
|
||||
## Dignity / Role Guardrails
|
||||
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
{
|
||||
"scope": "vedastro_parity_matrix",
|
||||
"schema_version": 1,
|
||||
"generated_at": "2026-06-28T08:31:52.958980+00:00",
|
||||
"summary": {
|
||||
"row_count": 13,
|
||||
"p0_count": 11,
|
||||
"status_counts": {
|
||||
"partial": 8,
|
||||
"covered": 4,
|
||||
"missing": 1
|
||||
},
|
||||
"recommended_path_counts": {
|
||||
"hybrid_local_plus_vedastro": 7,
|
||||
"local_native": 4,
|
||||
"new_local_impl": 1,
|
||||
"external_evidence_only": 1
|
||||
},
|
||||
"local_registry_technique_count": 89
|
||||
},
|
||||
"boundary": {
|
||||
"not_a_clone_claim": true,
|
||||
"external_outputs_are_adapter_evidence_until_promoted": true,
|
||||
"local_adjudicator_remains_final_reasoning_layer": true
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"vedastro_capability": "Tajika Annual",
|
||||
"category": "annual_prediction",
|
||||
"local_status": "partial",
|
||||
"local_assets": [
|
||||
"tajika.py",
|
||||
"varshaphala.py",
|
||||
"sahams",
|
||||
"solar_return"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_external_oracle",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Annual modules exist; yearly career/wealth/month windows need stronger strict-workflow integration."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Ayanamsa Selection",
|
||||
"category": "ephemeris_policy",
|
||||
"local_status": "partial",
|
||||
"local_assets": [
|
||||
"ayanamsa_utils",
|
||||
"ephemeris_adapter_contract"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "external_service_or_clean_room_only",
|
||||
"adjudicator_use": "oracle_only",
|
||||
"gap_notes": "Local Lahiri path is usable, but broad ayanamsa parity and public comparison artifacts remain incomplete."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Prashna / Horary",
|
||||
"category": "horary",
|
||||
"local_status": "covered",
|
||||
"local_assets": [
|
||||
"prashna.py",
|
||||
"kp_system.py",
|
||||
"upagraha_gulika_maandi",
|
||||
"sphuta_trisphuta_family"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "local_native",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_clean_room",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Horary modules exist but are not yet a first-class question adjudicator route."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Jaimini / Chara Dasha",
|
||||
"category": "jaimini",
|
||||
"local_status": "covered",
|
||||
"local_assets": [
|
||||
"jaimini.py",
|
||||
"AK",
|
||||
"DK",
|
||||
"UL",
|
||||
"Chara Dasha",
|
||||
"Jaimini marriage bridge v1"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "local_native",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_mit_attribution_for_reused_parts",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Core Jaimini exists; mission/career/marriage quality adjudicator folding is not yet exhaustive."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Report Rendering",
|
||||
"category": "presentation",
|
||||
"local_status": "partial",
|
||||
"local_assets": [
|
||||
"report_artifact API",
|
||||
"report_builder.py",
|
||||
"chart_renderer.py",
|
||||
"jyotish-app export"
|
||||
],
|
||||
"can_call_vedastro": false,
|
||||
"recommended_path": "new_local_impl",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native",
|
||||
"adjudicator_use": "not_used",
|
||||
"gap_notes": "HTML/PDF artifact path exists; polished SVG/PDF chart rendering and cloud-scale report production are not finished."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Synastry / Ashtakoot",
|
||||
"category": "relationship_matching",
|
||||
"local_status": "covered",
|
||||
"local_assets": [
|
||||
"synastry.py",
|
||||
"ashtakoot.py",
|
||||
"36-point Ashtakoot",
|
||||
"16-factor compatibility"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "local_native",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_mit_attribution_for_reused_parts",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Matching modules exist and API-backed; relationship adjudicator still needs a formal bridge."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "MCP / API Surface",
|
||||
"category": "service_surface",
|
||||
"local_status": "partial",
|
||||
"local_assets": [
|
||||
"mcp_server.py",
|
||||
"jyotish_api_server.py",
|
||||
"strict workflows",
|
||||
"vedastro_service_adapter.py"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "external_service_or_local_native",
|
||||
"adjudicator_use": "primary",
|
||||
"gap_notes": "Local API/MCP surfaces exist; VedAstro live adapter needs endpoint-backed smoke tests and provenance capture."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Ashtakavarga",
|
||||
"category": "strength",
|
||||
"local_status": "partial",
|
||||
"local_assets": [
|
||||
"ashtakavarga",
|
||||
"ashtakavarga_pav",
|
||||
"ashtakavarga_sodhita",
|
||||
"finance_ashtakavarga_bridge"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_external_oracle",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "SAV/BAV is in production; PAV/Sodhita/Kakshya bridges need continued regression before being dominant labels."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Shadbala",
|
||||
"category": "strength",
|
||||
"local_status": "partial",
|
||||
"local_assets": [
|
||||
"shadbala",
|
||||
"shadbala_advanced",
|
||||
"shadbala_component_cap",
|
||||
"oracle_shadbala_queue"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_external_oracle",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Local component-aware cap exists; absolute external oracle closure is still incomplete."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "EventsAtRange / Life Event Graph",
|
||||
"category": "timing_range_scan",
|
||||
"local_status": "partial",
|
||||
"local_assets": [
|
||||
"transit_trigger",
|
||||
"dasha",
|
||||
"narayana_dasha",
|
||||
"vedastro_service_adapter.range_scan"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "external_service_or_clean_room_only",
|
||||
"adjudicator_use": "oracle_only",
|
||||
"gap_notes": "Local timing modules exist, but a high-frequency day/hour event graph is not yet a local productized radar."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "D1-D60 Divisional Charts",
|
||||
"category": "varga",
|
||||
"local_status": "covered",
|
||||
"local_assets": [
|
||||
"varga",
|
||||
"varga_full",
|
||||
"shodasavarga",
|
||||
"divisional_charts_extended"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "local_native",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_clean_room",
|
||||
"adjudicator_use": "primary",
|
||||
"gap_notes": "Local varga coverage is strong; keep VedAstro/PyJHora as benchmark evidence rather than replacing local math."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Birth Time ML / Rectification Assistant",
|
||||
"category": "birth_time_rectification",
|
||||
"local_status": "partial",
|
||||
"local_assets": [
|
||||
"birth_time_rectifier.py",
|
||||
"rectification_gate",
|
||||
"jyotish-app rectification"
|
||||
],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P1",
|
||||
"license_boundary": "external_service_or_local_native",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Local rectification exists; ML parity with VedAstro-style service behavior is not established."
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Numerology / Non-Jyotish Tools",
|
||||
"category": "adjacent_tools",
|
||||
"local_status": "missing",
|
||||
"local_assets": [],
|
||||
"can_call_vedastro": true,
|
||||
"recommended_path": "external_evidence_only",
|
||||
"priority": "P2",
|
||||
"license_boundary": "external_service_only",
|
||||
"adjudicator_use": "not_used",
|
||||
"gap_notes": "Adjacent product feature; not required for Jyotish adjudicator depth."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
# VedAstro Parity Matrix
|
||||
|
||||
- Generated: `2026-06-28T08:31:52.958980+00:00`
|
||||
- Rows: `13`
|
||||
- P0 rows: `11`
|
||||
- Local registry technique count: `89`
|
||||
|
||||
## Honesty Boundary
|
||||
|
||||
VedAstro calls are external adapter evidence until a capability is promoted by local tests, oracle artifacts, or strict workflow integration. This matrix does not claim clone-level parity.
|
||||
|
||||
## Summary
|
||||
|
||||
- Local status counts: `{"covered": 4, "missing": 1, "partial": 8}`
|
||||
- Recommended path counts: `{"external_evidence_only": 1, "hybrid_local_plus_vedastro": 7, "local_native": 4, "new_local_impl": 1}`
|
||||
|
||||
## Matrix
|
||||
|
||||
| VedAstro capability | Category | Local status | Path | Priority | Adjudicator use | Local assets | Gap notes |
|
||||
|---|---|---:|---|---:|---|---|---|
|
||||
| Tajika Annual | annual_prediction | partial | hybrid_local_plus_vedastro | P0 | secondary | tajika.py, varshaphala.py, sahams, solar_return | Annual modules exist; yearly career/wealth/month windows need stronger strict-workflow integration. |
|
||||
| Ayanamsa Selection | ephemeris_policy | partial | hybrid_local_plus_vedastro | P0 | oracle_only | ayanamsa_utils, ephemeris_adapter_contract | Local Lahiri path is usable, but broad ayanamsa parity and public comparison artifacts remain incomplete. |
|
||||
| Prashna / Horary | horary | covered | local_native | P0 | secondary | prashna.py, kp_system.py, upagraha_gulika_maandi, sphuta_trisphuta_family | Horary modules exist but are not yet a first-class question adjudicator route. |
|
||||
| Jaimini / Chara Dasha | jaimini | covered | local_native | P0 | secondary | jaimini.py, AK, DK, UL, Chara Dasha, Jaimini marriage bridge v1 | Core Jaimini exists; mission/career/marriage quality adjudicator folding is not yet exhaustive. |
|
||||
| Report Rendering | presentation | partial | new_local_impl | P0 | not_used | report_artifact API, report_builder.py, chart_renderer.py, jyotish-app export | HTML/PDF artifact path exists; polished SVG/PDF chart rendering and cloud-scale report production are not finished. |
|
||||
| Synastry / Ashtakoot | relationship_matching | covered | local_native | P0 | secondary | synastry.py, ashtakoot.py, 36-point Ashtakoot, 16-factor compatibility | Matching modules exist and API-backed; relationship adjudicator still needs a formal bridge. |
|
||||
| MCP / API Surface | service_surface | partial | hybrid_local_plus_vedastro | P0 | primary | mcp_server.py, jyotish_api_server.py, strict workflows, vedastro_service_adapter.py | Local API/MCP surfaces exist; VedAstro live adapter needs endpoint-backed smoke tests and provenance capture. |
|
||||
| Ashtakavarga | strength | partial | hybrid_local_plus_vedastro | P0 | secondary | ashtakavarga, ashtakavarga_pav, ashtakavarga_sodhita, finance_ashtakavarga_bridge | SAV/BAV is in production; PAV/Sodhita/Kakshya bridges need continued regression before being dominant labels. |
|
||||
| Shadbala | strength | partial | hybrid_local_plus_vedastro | P0 | secondary | shadbala, shadbala_advanced, shadbala_component_cap, oracle_shadbala_queue | Local component-aware cap exists; absolute external oracle closure is still incomplete. |
|
||||
| EventsAtRange / Life Event Graph | timing_range_scan | partial | hybrid_local_plus_vedastro | P0 | oracle_only | transit_trigger, dasha, narayana_dasha, vedastro_service_adapter.range_scan | Local timing modules exist, but a high-frequency day/hour event graph is not yet a local productized radar. |
|
||||
| D1-D60 Divisional Charts | varga | covered | local_native | P0 | primary | varga, varga_full, shodasavarga, divisional_charts_extended | Local varga coverage is strong; keep VedAstro/PyJHora as benchmark evidence rather than replacing local math. |
|
||||
| Birth Time ML / Rectification Assistant | birth_time_rectification | partial | hybrid_local_plus_vedastro | P1 | secondary | birth_time_rectifier.py, rectification_gate, jyotish-app rectification | Local rectification exists; ML parity with VedAstro-style service behavior is not established. |
|
||||
| Numerology / Non-Jyotish Tools | adjacent_tools | missing | external_evidence_only | P2 | not_used | - | Adjacent product feature; not required for Jyotish adjudicator depth. |
|
||||
|
||||
## Next Actions
|
||||
|
||||
1. Promote `VedAstro adapter MVP` from contract to endpoint-backed smoke tests.
|
||||
2. Add a relationship bridge for `Synastry / Ashtakoot` before using matching scores as primary labels.
|
||||
3. Build `Life Event Graph v1` from local monthly/day scan plus optional VedAstro range-scan evidence.
|
||||
4. Keep ayanamsa and Shadbala parity under oracle closure before claiming production tuning.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# VedAstro Parity Matrix v1 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:** Build a repeatable VedAstro parity matrix that maps public VedAstro capability areas to local assets, external adapter options, and implementation priorities.
|
||||
|
||||
**Architecture:** Add one focused generator script that consumes local capability audit output and a curated VedAstro seed list, then writes JSON and Markdown snapshots. Keep the matrix separate from strict adjudicator runtime so it cannot accidentally assert unverified production parity.
|
||||
|
||||
**Tech Stack:** Python 3 standard library, existing `scripts/audit_capabilities.py`, existing research markdown conventions.
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Do not copy VedAstro implementation code.
|
||||
- Treat VedAstro results as external adapter evidence unless promoted by local tests or oracle artifacts.
|
||||
- Do not modify strict workflow scoring in this task.
|
||||
- Do not stage unrelated untracked workspace residue.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Generator And Tests
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/vedastro_parity_matrix.py`
|
||||
- Create: `tests/test_vedastro_parity_matrix.py`
|
||||
- Modify: `docs/research/ACTIVE_FRONTS.md`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `build_matrix(audit: dict | None = None) -> dict`
|
||||
- Produces: `render_markdown(matrix: dict) -> str`
|
||||
- Produces CLI: `python3 scripts/vedastro_parity_matrix.py --format json|markdown --write`
|
||||
|
||||
- [ ] **Step 1: Write tests for P0 rows and contracts**
|
||||
|
||||
Run: `python3 -m pytest tests/test_vedastro_parity_matrix.py -q`
|
||||
|
||||
- [ ] **Step 2: Implement the generator**
|
||||
|
||||
Create the matrix with deterministic row ordering and explicit allowed values.
|
||||
|
||||
- [ ] **Step 3: Generate snapshots**
|
||||
|
||||
Run: `python3 scripts/vedastro_parity_matrix.py --write`
|
||||
|
||||
- [ ] **Step 4: Verify**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python3 -m pytest tests/test_vedastro_parity_matrix.py -q
|
||||
python3 scripts/vedastro_parity_matrix.py --format json >/tmp/vedastro_parity_matrix.json
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
Stage only the parity matrix files, tests, and Active Fronts update.
|
||||
@@ -0,0 +1,47 @@
|
||||
# VedAstro Parity Matrix v1 Design
|
||||
|
||||
## Goal
|
||||
|
||||
Create a repeatable parity matrix that compares public VedAstro capability areas with this repository's local assets and recommends the safest integration path for each area.
|
||||
|
||||
## Boundary
|
||||
|
||||
The matrix is a planning and audit artifact. It does not claim that local behavior equals VedAstro behavior unless the local registry, tests, and external oracle status support that claim.
|
||||
|
||||
## Inputs
|
||||
|
||||
- `scripts/audit_capabilities.py --mode validate`
|
||||
- `scripts/vedastro_service_adapter.py` schema and supported range-scan domains
|
||||
- A curated public VedAstro capability seed list kept in the generator script
|
||||
- Existing research indexes under `docs/research/ACTIVE_FRONTS.md`
|
||||
|
||||
## Output Contract
|
||||
|
||||
Each row includes:
|
||||
|
||||
- `vedastro_capability`
|
||||
- `category`
|
||||
- `local_status`
|
||||
- `local_assets`
|
||||
- `can_call_vedastro`
|
||||
- `recommended_path`
|
||||
- `priority`
|
||||
- `license_boundary`
|
||||
- `adjudicator_use`
|
||||
- `gap_notes`
|
||||
|
||||
Allowed `recommended_path` values:
|
||||
|
||||
- `local_native`
|
||||
- `vedastro_adapter`
|
||||
- `new_local_impl`
|
||||
- `external_evidence_only`
|
||||
- `hybrid_local_plus_vedastro`
|
||||
|
||||
## v1 Priorities
|
||||
|
||||
P0 rows cover: range scanning, ayanamsa parity, D1-D60/varga parity, Ashtakavarga/Shadbala oracle checks, Jaimini/Chara Dasha, Synastry/Ashtakoot, Tajika annual, Prashna, report rendering, and MCP/API parity.
|
||||
|
||||
## Honesty Rule
|
||||
|
||||
External VedAstro output must be marked as adapter evidence unless it is independently promoted through local tests or an oracle artifact. Local adjudicators remain the final reasoning layer.
|
||||
@@ -0,0 +1,351 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build a VedAstro-to-local parity matrix.
|
||||
|
||||
The matrix is an audit/planning artifact. It keeps VedAstro service evidence,
|
||||
local native implementation, and adjudicator use separate so external API
|
||||
coverage is not mislabeled as local production parity.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
DEFAULT_JSON_PATH = ROOT / "docs" / "research" / "vedastro_parity_matrix_latest.json"
|
||||
DEFAULT_MARKDOWN_PATH = ROOT / "docs" / "research" / "vedastro_parity_matrix_latest.md"
|
||||
|
||||
ALLOWED_RECOMMENDED_PATHS = {
|
||||
"local_native",
|
||||
"vedastro_adapter",
|
||||
"new_local_impl",
|
||||
"external_evidence_only",
|
||||
"hybrid_local_plus_vedastro",
|
||||
}
|
||||
|
||||
|
||||
VEDASTRO_CAPABILITY_SEEDS: list[dict[str, Any]] = [
|
||||
{
|
||||
"vedastro_capability": "EventsAtRange / Life Event Graph",
|
||||
"category": "timing_range_scan",
|
||||
"domains": ["event", "timing", "transit"],
|
||||
"local_assets": ["transit_trigger", "dasha", "narayana_dasha", "vedastro_service_adapter.range_scan"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "external_service_or_clean_room_only",
|
||||
"adjudicator_use": "oracle_only",
|
||||
"gap_notes": "Local timing modules exist, but a high-frequency day/hour event graph is not yet a local productized radar.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Ayanamsa Selection",
|
||||
"category": "ephemeris_policy",
|
||||
"domains": ["core"],
|
||||
"local_assets": ["ayanamsa_utils", "ephemeris_adapter_contract"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "external_service_or_clean_room_only",
|
||||
"adjudicator_use": "oracle_only",
|
||||
"gap_notes": "Local Lahiri path is usable, but broad ayanamsa parity and public comparison artifacts remain incomplete.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "D1-D60 Divisional Charts",
|
||||
"category": "varga",
|
||||
"domains": ["varga", "divisional", "d60"],
|
||||
"local_assets": ["varga", "varga_full", "shodasavarga", "divisional_charts_extended"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "local_native",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_clean_room",
|
||||
"adjudicator_use": "primary",
|
||||
"gap_notes": "Local varga coverage is strong; keep VedAstro/PyJHora as benchmark evidence rather than replacing local math.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Ashtakavarga",
|
||||
"category": "strength",
|
||||
"domains": ["ashtakavarga", "strength"],
|
||||
"local_assets": ["ashtakavarga", "ashtakavarga_pav", "ashtakavarga_sodhita", "finance_ashtakavarga_bridge"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_external_oracle",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "SAV/BAV is in production; PAV/Sodhita/Kakshya bridges need continued regression before being dominant labels.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Shadbala",
|
||||
"category": "strength",
|
||||
"domains": ["shadbala", "strength"],
|
||||
"local_assets": ["shadbala", "shadbala_advanced", "shadbala_component_cap", "oracle_shadbala_queue"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_external_oracle",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Local component-aware cap exists; absolute external oracle closure is still incomplete.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Jaimini / Chara Dasha",
|
||||
"category": "jaimini",
|
||||
"domains": ["jaimini", "narayana", "karaka"],
|
||||
"local_assets": ["jaimini.py", "AK", "DK", "UL", "Chara Dasha", "Jaimini marriage bridge v1"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "local_native",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_mit_attribution_for_reused_parts",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Core Jaimini exists; mission/career/marriage quality adjudicator folding is not yet exhaustive.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Synastry / Ashtakoot",
|
||||
"category": "relationship_matching",
|
||||
"domains": ["synastry", "relationship", "marriage"],
|
||||
"local_assets": ["synastry.py", "ashtakoot.py", "36-point Ashtakoot", "16-factor compatibility"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "local_native",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_mit_attribution_for_reused_parts",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Matching modules exist and API-backed; relationship adjudicator still needs a formal bridge.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Tajika Annual",
|
||||
"category": "annual_prediction",
|
||||
"domains": ["tajika", "annual", "varshaphala", "saham"],
|
||||
"local_assets": ["tajika.py", "varshaphala.py", "sahams", "solar_return"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_external_oracle",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Annual modules exist; yearly career/wealth/month windows need stronger strict-workflow integration.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Prashna / Horary",
|
||||
"category": "horary",
|
||||
"domains": ["prashna", "kp"],
|
||||
"local_assets": ["prashna.py", "kp_system.py", "upagraha_gulika_maandi", "sphuta_trisphuta_family"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "local_native",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native_or_clean_room",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Horary modules exist but are not yet a first-class question adjudicator route.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Report Rendering",
|
||||
"category": "presentation",
|
||||
"domains": ["report", "image"],
|
||||
"local_assets": ["report_artifact API", "report_builder.py", "chart_renderer.py", "jyotish-app export"],
|
||||
"can_call_vedastro": False,
|
||||
"recommended_path": "new_local_impl",
|
||||
"priority": "P0",
|
||||
"license_boundary": "local_native",
|
||||
"adjudicator_use": "not_used",
|
||||
"gap_notes": "HTML/PDF artifact path exists; polished SVG/PDF chart rendering and cloud-scale report production are not finished.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "MCP / API Surface",
|
||||
"category": "service_surface",
|
||||
"domains": ["event", "relationship", "wealth", "career"],
|
||||
"local_assets": ["mcp_server.py", "jyotish_api_server.py", "strict workflows", "vedastro_service_adapter.py"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P0",
|
||||
"license_boundary": "external_service_or_local_native",
|
||||
"adjudicator_use": "primary",
|
||||
"gap_notes": "Local API/MCP surfaces exist; VedAstro live adapter needs endpoint-backed smoke tests and provenance capture.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Numerology / Non-Jyotish Tools",
|
||||
"category": "adjacent_tools",
|
||||
"domains": [],
|
||||
"local_assets": [],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "external_evidence_only",
|
||||
"priority": "P2",
|
||||
"license_boundary": "external_service_only",
|
||||
"adjudicator_use": "not_used",
|
||||
"gap_notes": "Adjacent product feature; not required for Jyotish adjudicator depth.",
|
||||
},
|
||||
{
|
||||
"vedastro_capability": "Birth Time ML / Rectification Assistant",
|
||||
"category": "birth_time_rectification",
|
||||
"domains": ["birth"],
|
||||
"local_assets": ["birth_time_rectifier.py", "rectification_gate", "jyotish-app rectification"],
|
||||
"can_call_vedastro": True,
|
||||
"recommended_path": "hybrid_local_plus_vedastro",
|
||||
"priority": "P1",
|
||||
"license_boundary": "external_service_or_local_native",
|
||||
"adjudicator_use": "secondary",
|
||||
"gap_notes": "Local rectification exists; ML parity with VedAstro-style service behavior is not established.",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def _run_audit_capabilities() -> dict[str, Any]:
|
||||
proc = subprocess.run(
|
||||
[sys.executable, "scripts/audit_capabilities.py", "--mode", "validate"],
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
return json.loads(proc.stdout)
|
||||
|
||||
|
||||
def _infer_local_status(seed: dict[str, Any], audit: dict[str, Any]) -> str:
|
||||
domain_counts = audit.get("domain_counts") if isinstance(audit, dict) else {}
|
||||
status_counts = audit.get("status_counts") if isinstance(audit, dict) else {}
|
||||
domains = seed.get("domains") or []
|
||||
|
||||
if not seed.get("local_assets"):
|
||||
return "missing"
|
||||
|
||||
matched_domains = [domain for domain in domains if int(domain_counts.get(domain, 0) or 0) > 0]
|
||||
if matched_domains:
|
||||
if seed["recommended_path"] in {"new_local_impl", "hybrid_local_plus_vedastro"}:
|
||||
return "partial"
|
||||
return "covered" if int(status_counts.get("covered", 0) or 0) else "complete"
|
||||
|
||||
if seed["recommended_path"] == "external_evidence_only":
|
||||
return "external_only"
|
||||
return "partial"
|
||||
|
||||
|
||||
def _build_row(seed: dict[str, Any], audit: dict[str, Any]) -> dict[str, Any]:
|
||||
recommended_path = seed["recommended_path"]
|
||||
if recommended_path not in ALLOWED_RECOMMENDED_PATHS:
|
||||
raise ValueError(f"unsupported recommended_path: {recommended_path}")
|
||||
|
||||
return {
|
||||
"vedastro_capability": seed["vedastro_capability"],
|
||||
"category": seed["category"],
|
||||
"local_status": _infer_local_status(seed, audit),
|
||||
"local_assets": list(seed["local_assets"]),
|
||||
"can_call_vedastro": bool(seed["can_call_vedastro"]),
|
||||
"recommended_path": recommended_path,
|
||||
"priority": seed["priority"],
|
||||
"license_boundary": seed["license_boundary"],
|
||||
"adjudicator_use": seed["adjudicator_use"],
|
||||
"gap_notes": seed["gap_notes"],
|
||||
}
|
||||
|
||||
|
||||
def build_matrix(audit: dict[str, Any] | None = None) -> dict[str, Any]:
|
||||
audit = audit if audit is not None else _run_audit_capabilities()
|
||||
rows = [_build_row(seed, audit) for seed in VEDASTRO_CAPABILITY_SEEDS]
|
||||
rows.sort(key=lambda row: (row["priority"], row["category"], row["vedastro_capability"]))
|
||||
|
||||
status_counts: dict[str, int] = {}
|
||||
path_counts: dict[str, int] = {}
|
||||
priority_counts: dict[str, int] = {}
|
||||
for row in rows:
|
||||
status_counts[row["local_status"]] = status_counts.get(row["local_status"], 0) + 1
|
||||
path_counts[row["recommended_path"]] = path_counts.get(row["recommended_path"], 0) + 1
|
||||
priority_counts[row["priority"]] = priority_counts.get(row["priority"], 0) + 1
|
||||
|
||||
return {
|
||||
"scope": "vedastro_parity_matrix",
|
||||
"schema_version": 1,
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"summary": {
|
||||
"row_count": len(rows),
|
||||
"p0_count": priority_counts.get("P0", 0),
|
||||
"status_counts": status_counts,
|
||||
"recommended_path_counts": path_counts,
|
||||
"local_registry_technique_count": audit.get("technique_count"),
|
||||
},
|
||||
"boundary": {
|
||||
"not_a_clone_claim": True,
|
||||
"external_outputs_are_adapter_evidence_until_promoted": True,
|
||||
"local_adjudicator_remains_final_reasoning_layer": True,
|
||||
},
|
||||
"rows": rows,
|
||||
}
|
||||
|
||||
|
||||
def render_markdown(matrix: dict[str, Any]) -> str:
|
||||
summary = matrix["summary"]
|
||||
lines = [
|
||||
"# VedAstro Parity Matrix",
|
||||
"",
|
||||
f"- Generated: `{matrix['generated_at']}`",
|
||||
f"- Rows: `{summary['row_count']}`",
|
||||
f"- P0 rows: `{summary['p0_count']}`",
|
||||
f"- Local registry technique count: `{summary.get('local_registry_technique_count')}`",
|
||||
"",
|
||||
"## Honesty Boundary",
|
||||
"",
|
||||
"VedAstro calls are external adapter evidence until a capability is promoted by local tests, oracle artifacts, or strict workflow integration. This matrix does not claim clone-level parity.",
|
||||
"",
|
||||
"## Summary",
|
||||
"",
|
||||
f"- Local status counts: `{json.dumps(summary['status_counts'], ensure_ascii=False, sort_keys=True)}`",
|
||||
f"- Recommended path counts: `{json.dumps(summary['recommended_path_counts'], ensure_ascii=False, sort_keys=True)}`",
|
||||
"",
|
||||
"## Matrix",
|
||||
"",
|
||||
"| VedAstro capability | Category | Local status | Path | Priority | Adjudicator use | Local assets | Gap notes |",
|
||||
"|---|---|---:|---|---:|---|---|---|",
|
||||
]
|
||||
for row in matrix["rows"]:
|
||||
assets = ", ".join(row["local_assets"]) if row["local_assets"] else "-"
|
||||
lines.append(
|
||||
"| {vedastro_capability} | {category} | {local_status} | {recommended_path} | {priority} | {adjudicator_use} | {assets} | {gap_notes} |".format(
|
||||
assets=assets,
|
||||
**row,
|
||||
)
|
||||
)
|
||||
lines.extend(
|
||||
[
|
||||
"",
|
||||
"## Next Actions",
|
||||
"",
|
||||
"1. Promote `VedAstro adapter MVP` from contract to endpoint-backed smoke tests.",
|
||||
"2. Add a relationship bridge for `Synastry / Ashtakoot` before using matching scores as primary labels.",
|
||||
"3. Build `Life Event Graph v1` from local monthly/day scan plus optional VedAstro range-scan evidence.",
|
||||
"4. Keep ayanamsa and Shadbala parity under oracle closure before claiming production tuning.",
|
||||
"",
|
||||
]
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def write_outputs(
|
||||
matrix: dict[str, Any],
|
||||
*,
|
||||
json_path: Path = DEFAULT_JSON_PATH,
|
||||
markdown_path: Path = DEFAULT_MARKDOWN_PATH,
|
||||
) -> None:
|
||||
json_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
markdown_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
json_path.write_text(json.dumps(matrix, ensure_ascii=False, indent=2) + "\n")
|
||||
markdown_path.write_text(render_markdown(matrix) + "\n")
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--format", choices=["json", "markdown"], default="json")
|
||||
parser.add_argument("--write", action="store_true", help="write latest JSON and Markdown snapshots")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
matrix = build_matrix()
|
||||
if args.write:
|
||||
write_outputs(matrix)
|
||||
if args.format == "json":
|
||||
print(json.dumps(matrix, ensure_ascii=False, indent=2))
|
||||
else:
|
||||
print(render_markdown(matrix))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,116 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from scripts import vedastro_parity_matrix
|
||||
|
||||
|
||||
def _row(matrix, capability):
|
||||
for row in matrix["rows"]:
|
||||
if row["vedastro_capability"] == capability:
|
||||
return row
|
||||
raise AssertionError(f"missing row: {capability}")
|
||||
|
||||
|
||||
def test_build_matrix_has_p0_public_vedastro_capability_rows():
|
||||
matrix = vedastro_parity_matrix.build_matrix()
|
||||
|
||||
assert matrix["scope"] == "vedastro_parity_matrix"
|
||||
assert matrix["summary"]["row_count"] >= 10
|
||||
assert matrix["summary"]["p0_count"] >= 10
|
||||
|
||||
required = {
|
||||
"EventsAtRange / Life Event Graph",
|
||||
"Ayanamsa Selection",
|
||||
"D1-D60 Divisional Charts",
|
||||
"Ashtakavarga",
|
||||
"Shadbala",
|
||||
"Jaimini / Chara Dasha",
|
||||
"Synastry / Ashtakoot",
|
||||
"Tajika Annual",
|
||||
"Prashna / Horary",
|
||||
"Report Rendering",
|
||||
"MCP / API Surface",
|
||||
}
|
||||
assert required.issubset({row["vedastro_capability"] for row in matrix["rows"]})
|
||||
|
||||
|
||||
def test_range_scan_is_adapter_gap_not_local_complete_claim():
|
||||
matrix = vedastro_parity_matrix.build_matrix()
|
||||
row = _row(matrix, "EventsAtRange / Life Event Graph")
|
||||
|
||||
assert row["priority"] == "P0"
|
||||
assert row["local_status"] in {"partial", "missing"}
|
||||
assert row["can_call_vedastro"] is True
|
||||
assert row["recommended_path"] == "hybrid_local_plus_vedastro"
|
||||
assert row["adjudicator_use"] == "oracle_only"
|
||||
assert "range" in " ".join(row["local_assets"]).lower()
|
||||
|
||||
|
||||
def test_local_assets_still_need_parity_or_bridge_when_not_fully_exploited():
|
||||
matrix = vedastro_parity_matrix.build_matrix()
|
||||
|
||||
jaimini = _row(matrix, "Jaimini / Chara Dasha")
|
||||
assert jaimini["local_status"] in {"covered", "complete"}
|
||||
assert "jaimini" in " ".join(jaimini["local_assets"]).lower()
|
||||
assert jaimini["recommended_path"] in {"local_native", "hybrid_local_plus_vedastro"}
|
||||
|
||||
synastry = _row(matrix, "Synastry / Ashtakoot")
|
||||
assert synastry["local_status"] in {"covered", "complete"}
|
||||
assert any("ashtakoot" in asset.lower() for asset in synastry["local_assets"])
|
||||
assert synastry["adjudicator_use"] in {"secondary", "primary"}
|
||||
|
||||
|
||||
def test_matrix_rows_use_allowed_contract_values():
|
||||
matrix = vedastro_parity_matrix.build_matrix()
|
||||
|
||||
allowed_status = {"complete", "covered", "partial", "missing", "external_only"}
|
||||
allowed_path = {
|
||||
"local_native",
|
||||
"vedastro_adapter",
|
||||
"new_local_impl",
|
||||
"external_evidence_only",
|
||||
"hybrid_local_plus_vedastro",
|
||||
}
|
||||
allowed_priority = {"P0", "P1", "P2"}
|
||||
allowed_use = {"primary", "secondary", "oracle_only", "not_used"}
|
||||
|
||||
for row in matrix["rows"]:
|
||||
assert set(row) == {
|
||||
"vedastro_capability",
|
||||
"category",
|
||||
"local_status",
|
||||
"local_assets",
|
||||
"can_call_vedastro",
|
||||
"recommended_path",
|
||||
"priority",
|
||||
"license_boundary",
|
||||
"adjudicator_use",
|
||||
"gap_notes",
|
||||
}
|
||||
assert row["local_status"] in allowed_status
|
||||
assert row["recommended_path"] in allowed_path
|
||||
assert row["priority"] in allowed_priority
|
||||
assert row["adjudicator_use"] in allowed_use
|
||||
assert isinstance(row["local_assets"], list)
|
||||
|
||||
|
||||
def test_render_markdown_contains_summary_and_honesty_boundary():
|
||||
matrix = vedastro_parity_matrix.build_matrix()
|
||||
markdown = vedastro_parity_matrix.render_markdown(matrix)
|
||||
|
||||
assert "# VedAstro Parity Matrix" in markdown
|
||||
assert "## Honesty Boundary" in markdown
|
||||
assert "EventsAtRange / Life Event Graph" in markdown
|
||||
assert "external adapter evidence" in markdown
|
||||
|
||||
|
||||
def test_write_outputs_creates_json_and_markdown(tmp_path):
|
||||
matrix = vedastro_parity_matrix.build_matrix()
|
||||
json_path = tmp_path / "matrix.json"
|
||||
md_path = tmp_path / "matrix.md"
|
||||
|
||||
vedastro_parity_matrix.write_outputs(matrix, json_path=json_path, markdown_path=md_path)
|
||||
|
||||
loaded = json.loads(json_path.read_text())
|
||||
assert loaded["scope"] == "vedastro_parity_matrix"
|
||||
assert md_path.read_text().startswith("# VedAstro Parity Matrix")
|
||||
Reference in New Issue
Block a user