test: import research oracle probes
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# Jyotishyamitra Pinned Adapter Probe - 2026-07-18
|
||||
|
||||
## Status
|
||||
|
||||
`jyotishyamitra` is pinned as a fourth independent observation oracle only.
|
||||
|
||||
It is not part of the three-engine truth matrix and does not promote any claim.
|
||||
|
||||
## Identity
|
||||
|
||||
- Package: `jyotishyamitra`
|
||||
- Version: `1.4.0`
|
||||
- GitHub commit: `86f7eb610a66b06b3f0817d2c53355bec8b3bf8d`
|
||||
- License: MIT in wheel license file
|
||||
- Wheel SHA-256: `4f1a16facfa86ef01cb44de505c6de2e66b2f8d2c8b5e125c090e3f8485c6a9d`
|
||||
- Python wheel tag: `py3-none-any`
|
||||
- Requires Python: `>=3.7`
|
||||
|
||||
## Execution Boundary
|
||||
|
||||
- Adapter: `scripts/jyotishyamitra_adapter_probe.py`
|
||||
- Tests: `tests/test_jyotishyamitra_adapter_probe.py`
|
||||
- The wheel is installed with `pip --target` into a temporary directory.
|
||||
- The package is invoked in an isolated subprocess with temporary `PYTHONPATH`.
|
||||
- `jyotishyamitra` is not a project runtime dependency and is not imported by commercial runtime code.
|
||||
- No implementation code is copied from the package.
|
||||
|
||||
## Canonical Request
|
||||
|
||||
The Steve Jobs probe records:
|
||||
|
||||
- birth: `1955-02-24 19:15:00`
|
||||
- place: `San Francisco, CA`
|
||||
- longitude: `-122.4194`
|
||||
- latitude: `37.7749`
|
||||
- timezone: `-8.0`
|
||||
- ayanamsa: `package_default`
|
||||
- node mode: `package_default`
|
||||
- returnval: `ASTRODATA_DICTIONARY`
|
||||
|
||||
## Artifacts
|
||||
|
||||
- Metadata-only: `references/oracle/jyotishyamitra_pinned_adapter_probe_2026_07_18.json`
|
||||
- Steve Jobs execution probe: `references/oracle/jyotishyamitra_steve_jobs_probe_2026_07_18.json`
|
||||
|
||||
The input contract issue was resolved: `input_birthdata()` returns string-valued input, while `generate_astrologicalData()` needs the numeric `get_birthdata()` object after `validate_birthdata() == "SUCCESS"`.
|
||||
|
||||
The Steve Jobs run now returns structured dictionary raw with top-level keys including `D1`, `D2`, `D4`, `D9`, `D10`, `Balas`, `AshtakaVarga`, and `Dashas`.
|
||||
|
||||
Replay stability:
|
||||
|
||||
- full raw hash: intentionally unstable because `$.Dashas.Vimshottari.current.date` embeds run time.
|
||||
- normalized raw hash: stable after replacing `$.Dashas.Vimshottari.current.date` with `<volatile_run_time>`.
|
||||
- normalized raw SHA-256: `b749d78f42a43aa4e5b647230a7e317602de21e3308a0a650c0e662c630546cf`
|
||||
- schema SHA-256: `4ed38f03ddc8774b48501969c31c0a9ad87de3e2a4b5bc293cd86280467bc858`
|
||||
- schema path count: `13524`
|
||||
|
||||
## Next
|
||||
|
||||
1. Extract D1/D2/D4/D9/D10, Shadbala/Balas, AshtakaVarga, and Vimshottari fields.
|
||||
2. Compare field-by-field against local, Xalen, PyJHora, and jyotishganit as independent observation only.
|
||||
3. Keep `promotion_allowed=false` unless external worked examples arbitrate method variants.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Oracle Blocker Resolution Attempt - 2026-07-17
|
||||
|
||||
## Summary
|
||||
|
||||
This pass converts the three non-fakeable blockers into executable evidence gates.
|
||||
|
||||
## VedAstro hosted identity / output drift
|
||||
|
||||
- Added `scripts/vedastro_identity_archive.py`.
|
||||
- Archived NuGet self-host candidate identity for `VedAstro.Library` `1.2.0`:
|
||||
- package hash algorithm: `SHA512`
|
||||
- NuGet catalog commit: `c707690b-f7bd-4813-a2cb-876e943e9667`
|
||||
- license: `MIT`
|
||||
- target framework dependencies include `SwissEphNet [2.8.0.2, )`
|
||||
- Evidence: `references/oracle/vedastro_reproducible_identity_archive_2026_07_17.json`.
|
||||
- Boundary: this fixes a reproducible NuGet package identity only. It does not prove `api.vedastro.org` runs that package, DLL, container, or method semantics.
|
||||
- Status: `hosted_api_status=blocked`.
|
||||
|
||||
## Timing independent negative holdout
|
||||
|
||||
- Added `scripts/timing_negative_holdout_audit.py`.
|
||||
- Audited current candidate sources:
|
||||
- public positive timelines are not negative labels.
|
||||
- existing 40 control dates are observed and not independently reviewed, so diagnostic only.
|
||||
- Evidence: `references/real_case_calibration/timing_negative_holdout_source_audit_2026_07_17.json`.
|
||||
- Output policy remains: return ranked `candidate_day_window` with `claim_status=exploratory_unvalidated`; do not label day/month candidates as verified predictions.
|
||||
|
||||
## Xalen / Shadbala / Ashtakavarga arbitration
|
||||
|
||||
- Added `scripts/xalen_arbitration_gate.py`.
|
||||
- Regenerated:
|
||||
- `references/oracle/xalen_formula_unit_attribution_2026_07_17.json`
|
||||
- `references/oracle/xalen_public_case_batch_2026_07_17.json`
|
||||
- `references/oracle/xalen_ephemeris_mode_comparison_2026_07_17.json`
|
||||
- `references/oracle/xalen_formula_arbitration_gate_2026_07_17.json`
|
||||
- Five public AA cases replayed.
|
||||
- Independent ephemeris comparison remains ready:
|
||||
- max longitude delta: `0.005305966338369217` degrees
|
||||
- varga differences: `0`
|
||||
- Gate result: `truth_status=blocked`, `unresolved_variant_count=46`, `promotion_allowed=false`.
|
||||
- Boundary: multi-case replay and independent ephemeris reduce implementation risk; they do not arbitrate formula variants without external numeric worked examples.
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"boundary": "Adapter calls the installed MIT package as an oracle; it does not copy implementation or promote conclusions.",
|
||||
"canonical_request": {},
|
||||
"comparison": {},
|
||||
"isolated_subprocess": {
|
||||
"returncode": null,
|
||||
"stderr": null,
|
||||
"temporary_install_path": null,
|
||||
"used": false
|
||||
},
|
||||
"license": "MIT",
|
||||
"normalization": {
|
||||
"purpose": "remove run timestamp before replay comparison",
|
||||
"volatile_paths": [
|
||||
"$.Dashas.Vimshottari.current.date"
|
||||
]
|
||||
},
|
||||
"normalized_raw_sha256": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
|
||||
"oracle": "jyotishyamitra",
|
||||
"package_metadata": {
|
||||
"license": null,
|
||||
"license_file_name": "jyotishyamitra-1.4.0.dist-info/licenses/LICENSE",
|
||||
"license_file_sha256": "e0d415c60630a798080e2971315a085320c9759cdd8c564a39646c3be9c7bbb0",
|
||||
"license_file_spdx_inferred": "MIT",
|
||||
"metadata_name": "jyotishyamitra-1.4.0.dist-info/METADATA",
|
||||
"metadata_sha256": "96fe0c3096a9e3eefbd3450efcce3619a09211a47733c3c49032029445fd0952",
|
||||
"name": "jyotishyamitra",
|
||||
"requires_python": ">=3.7",
|
||||
"summary": "This package takes the birth data as input and computes indian vedic astrological data in a json file or python dictionary format",
|
||||
"version": "1.4.0",
|
||||
"wheel_name": "jyotishyamitra-1.4.0.dist-info/WHEEL",
|
||||
"wheel_record_sha256": "ff309ddcdd65ebd02bc724dbf2bcc4a0ff53a5b61792a44548d383e4ebb19d3b",
|
||||
"wheel_tags": [
|
||||
"py3-none-any"
|
||||
]
|
||||
},
|
||||
"package_url": "https://pypi.org/project/jyotishyamitra/1.4.0/",
|
||||
"promotion_allowed": false,
|
||||
"python_runtime": {
|
||||
"executable": "/Library/Frameworks/Python.framework/Versions/3.11/bin/python3",
|
||||
"version": "3.11.9",
|
||||
"wheel_tags": [
|
||||
"py3-none-any"
|
||||
]
|
||||
},
|
||||
"raw": {},
|
||||
"raw_sha256": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
|
||||
"schema_fingerprint": {
|
||||
"path_count": 0,
|
||||
"sample_paths": [],
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"scope": "jyotishyamitra_pinned_adapter_probe",
|
||||
"source_commit": "86f7eb610a66b06b3f0817d2c53355bec8b3bf8d",
|
||||
"source_url": "https://github.com/VicharaVandana/jyotishyamitra/commit/86f7eb610a66b06b3f0817d2c53355bec8b3bf8d",
|
||||
"status": "metadata_only_or_input_blocked",
|
||||
"truth_policy": "independent_observation_not_truth",
|
||||
"version": "1.4.0",
|
||||
"wheel_path": "/tmp/jyotishyamitra_probe/jyotishyamitra-1.4.0-py3-none-any.whl",
|
||||
"wheel_sha256": "4f1a16facfa86ef01cb44de505c6de2e66b2f8d2c8b5e125c090e3f8485c6a9d"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"boundary": "This archive fixes a NuGet self-host candidate identity only; it does not prove the hosted API is running this package or the same method semantics.",
|
||||
"catalog_commit_id": "c707690b-f7bd-4813-a2cb-876e943e9667",
|
||||
"catalog_commit_timestamp": "2023-03-22T22:24:11.811524Z",
|
||||
"dependencies": [
|
||||
{
|
||||
"id": "ByteSize",
|
||||
"range": "[2.1.1, )",
|
||||
"target_framework": "net7.0"
|
||||
},
|
||||
{
|
||||
"id": "Google.Apis",
|
||||
"range": "[1.51.0, )",
|
||||
"target_framework": "net7.0"
|
||||
},
|
||||
{
|
||||
"id": "Google.Apis.Auth",
|
||||
"range": "[1.51.0, )",
|
||||
"target_framework": "net7.0"
|
||||
},
|
||||
{
|
||||
"id": "Google.Apis.Calendar.v3",
|
||||
"range": "[1.51.0.2237, )",
|
||||
"target_framework": "net7.0"
|
||||
},
|
||||
{
|
||||
"id": "Google.Apis.Core",
|
||||
"range": "[1.51.0, )",
|
||||
"target_framework": "net7.0"
|
||||
},
|
||||
{
|
||||
"id": "Microsoft.AspNetCore.Components.WebAssembly",
|
||||
"range": "[6.0.11, )",
|
||||
"target_framework": "net7.0"
|
||||
},
|
||||
{
|
||||
"id": "Microsoft.Extensions.Caching.Memory",
|
||||
"range": "[6.0.1, )",
|
||||
"target_framework": "net7.0"
|
||||
},
|
||||
{
|
||||
"id": "Microsoft.JSInterop",
|
||||
"range": "[6.0.11, )",
|
||||
"target_framework": "net7.0"
|
||||
},
|
||||
{
|
||||
"id": "SwissEphNet",
|
||||
"range": "[2.8.0.2, )",
|
||||
"target_framework": "net7.0"
|
||||
}
|
||||
],
|
||||
"hosted_api_blocker": "api.vedastro.org does not expose a verified build commit, package hash, DLL hash, assembly version, container digest, or method-semantics contract.",
|
||||
"hosted_api_status": "blocked",
|
||||
"license": "MIT",
|
||||
"nuget_catalog_url": "https://api.nuget.org/v3/catalog0/data/2023.03.22.22.24.11/vedastro.library.1.2.0.json",
|
||||
"nuget_registration_url": "https://api.nuget.org/v3/registration5-semver1/vedastro.library/1.2.0.json",
|
||||
"package": "VedAstro.Library",
|
||||
"package_content_url": "https://api.nuget.org/v3-flatcontainer/vedastro.library/1.2.0/vedastro.library.1.2.0.nupkg",
|
||||
"package_hash": "36gq1hggII7Ho27TSL2B85P0BQD1zsAE1xHoJgUrM9V5rnUJGXUZibDlutkXR9gJ+aMr8UCQa2771MfD6BAscA==",
|
||||
"package_hash_algorithm": "SHA512",
|
||||
"package_size": 230836,
|
||||
"project_url": "https://vedastro.org/",
|
||||
"published": "2023-03-22T22:22:01.81Z",
|
||||
"scope": "vedastro_reproducible_identity_archive",
|
||||
"self_host_candidate_status": "reproducible_package_identity_archived",
|
||||
"version": "1.2.0"
|
||||
}
|
||||
@@ -0,0 +1,485 @@
|
||||
{
|
||||
"case": {
|
||||
"name": "VP Jain published Shadbala example",
|
||||
"birth": "1981-09-13T01:30:00+05:30",
|
||||
"latitude": 28.65,
|
||||
"longitude": 77.2166666667,
|
||||
"ayanamsa": "Lahiri"
|
||||
},
|
||||
"source": {
|
||||
"upstream": "PyJHora 4.8.7 pvr_tests.py::shadbala_VPJainBook_tests",
|
||||
"upstream_issue": "https://github.com/naturalstupid/PyJHora/issues/17",
|
||||
"license_boundary": "Numeric published-example expectations only; no AGPL implementation copied."
|
||||
},
|
||||
"summary": {
|
||||
"row_count": 42,
|
||||
"classified_count": 42,
|
||||
"within_tolerance_count": 34,
|
||||
"method_variant_count": 8,
|
||||
"absolute_parity": false
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"component": "sthana",
|
||||
"planet": "Sun",
|
||||
"unit": "Virupa",
|
||||
"published_value": 172.04,
|
||||
"local_value": 157.05,
|
||||
"delta": -14.99,
|
||||
"tolerance": 1.0,
|
||||
"status": "method_variant",
|
||||
"variant": "moolatrikona_degree_range_vs_whole_sign"
|
||||
},
|
||||
{
|
||||
"component": "sthana",
|
||||
"planet": "Moon",
|
||||
"unit": "Virupa",
|
||||
"published_value": 77.17,
|
||||
"local_value": 77.17,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "sthana",
|
||||
"planet": "Mars",
|
||||
"unit": "Virupa",
|
||||
"published_value": 184.94,
|
||||
"local_value": 184.94,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "sthana",
|
||||
"planet": "Mercury",
|
||||
"unit": "Virupa",
|
||||
"published_value": 238.16,
|
||||
"local_value": 223.16,
|
||||
"delta": -15.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "method_variant",
|
||||
"variant": "moolatrikona_degree_range_vs_whole_sign"
|
||||
},
|
||||
{
|
||||
"component": "sthana",
|
||||
"planet": "Jupiter",
|
||||
"unit": "Virupa",
|
||||
"published_value": 152.98,
|
||||
"local_value": 152.97,
|
||||
"delta": -0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "sthana",
|
||||
"planet": "Venus",
|
||||
"unit": "Virupa",
|
||||
"published_value": 198.08,
|
||||
"local_value": 198.09,
|
||||
"delta": 0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "sthana",
|
||||
"planet": "Saturn",
|
||||
"unit": "Virupa",
|
||||
"published_value": 206.31,
|
||||
"local_value": 206.3,
|
||||
"delta": -0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "dig",
|
||||
"planet": "Sun",
|
||||
"unit": "Virupa",
|
||||
"published_value": 6.59,
|
||||
"local_value": 6.6,
|
||||
"delta": 0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "dig",
|
||||
"planet": "Moon",
|
||||
"unit": "Virupa",
|
||||
"published_value": 12.22,
|
||||
"local_value": 12.21,
|
||||
"delta": -0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "dig",
|
||||
"planet": "Mars",
|
||||
"unit": "Virupa",
|
||||
"published_value": 20.99,
|
||||
"local_value": 20.98,
|
||||
"delta": -0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "dig",
|
||||
"planet": "Mercury",
|
||||
"unit": "Virupa",
|
||||
"published_value": 31.97,
|
||||
"local_value": 31.97,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "dig",
|
||||
"planet": "Jupiter",
|
||||
"unit": "Virupa",
|
||||
"published_value": 31.99,
|
||||
"local_value": 31.99,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "dig",
|
||||
"planet": "Venus",
|
||||
"unit": "Virupa",
|
||||
"published_value": 53.29,
|
||||
"local_value": 53.29,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "dig",
|
||||
"planet": "Saturn",
|
||||
"unit": "Virupa",
|
||||
"published_value": 26.67,
|
||||
"local_value": 26.66,
|
||||
"delta": -0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "kala",
|
||||
"planet": "Sun",
|
||||
"unit": "Virupa",
|
||||
"published_value": 81.8,
|
||||
"local_value": 81.8,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "kala",
|
||||
"planet": "Moon",
|
||||
"unit": "Virupa",
|
||||
"published_value": 205.85,
|
||||
"local_value": 205.96,
|
||||
"delta": 0.11,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "kala",
|
||||
"planet": "Mars",
|
||||
"unit": "Virupa",
|
||||
"published_value": 158.08,
|
||||
"local_value": 158.34,
|
||||
"delta": 0.26,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "kala",
|
||||
"planet": "Mercury",
|
||||
"unit": "Virupa",
|
||||
"published_value": 210.68,
|
||||
"local_value": 211.48,
|
||||
"delta": 0.8,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "kala",
|
||||
"planet": "Jupiter",
|
||||
"unit": "Virupa",
|
||||
"published_value": 144.22,
|
||||
"local_value": 143.34,
|
||||
"delta": -0.88,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "kala",
|
||||
"planet": "Venus",
|
||||
"unit": "Virupa",
|
||||
"published_value": 135.89,
|
||||
"local_value": 135.84,
|
||||
"delta": -0.05,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "kala",
|
||||
"planet": "Saturn",
|
||||
"unit": "Virupa",
|
||||
"published_value": 139.56,
|
||||
"local_value": 139.63,
|
||||
"delta": 0.07,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "chesta",
|
||||
"planet": "Sun",
|
||||
"unit": "Virupa",
|
||||
"published_value": 0.0,
|
||||
"local_value": 70.14,
|
||||
"delta": 70.14,
|
||||
"tolerance": 1.0,
|
||||
"status": "method_variant",
|
||||
"variant": "luminary_chesta_policy"
|
||||
},
|
||||
{
|
||||
"component": "chesta",
|
||||
"planet": "Moon",
|
||||
"unit": "Virupa",
|
||||
"published_value": 0.0,
|
||||
"local_value": 108.76,
|
||||
"delta": 108.76,
|
||||
"tolerance": 1.0,
|
||||
"status": "method_variant",
|
||||
"variant": "luminary_chesta_policy"
|
||||
},
|
||||
{
|
||||
"component": "chesta",
|
||||
"planet": "Mars",
|
||||
"unit": "Virupa",
|
||||
"published_value": 20.93,
|
||||
"local_value": 19.25,
|
||||
"delta": -1.68,
|
||||
"tolerance": 1.0,
|
||||
"status": "method_variant",
|
||||
"variant": "mean_motion_seeghrochcha_variant"
|
||||
},
|
||||
{
|
||||
"component": "chesta",
|
||||
"planet": "Mercury",
|
||||
"unit": "Virupa",
|
||||
"published_value": 28.76,
|
||||
"local_value": 18.08,
|
||||
"delta": -10.68,
|
||||
"tolerance": 1.0,
|
||||
"status": "method_variant",
|
||||
"variant": "mean_motion_seeghrochcha_variant"
|
||||
},
|
||||
{
|
||||
"component": "chesta",
|
||||
"planet": "Jupiter",
|
||||
"unit": "Virupa",
|
||||
"published_value": 8.43,
|
||||
"local_value": 11.23,
|
||||
"delta": 2.8,
|
||||
"tolerance": 1.0,
|
||||
"status": "method_variant",
|
||||
"variant": "mean_motion_seeghrochcha_variant"
|
||||
},
|
||||
{
|
||||
"component": "chesta",
|
||||
"planet": "Venus",
|
||||
"unit": "Virupa",
|
||||
"published_value": 28.18,
|
||||
"local_value": 27.23,
|
||||
"delta": -0.95,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "chesta",
|
||||
"planet": "Saturn",
|
||||
"unit": "Virupa",
|
||||
"published_value": 5.05,
|
||||
"local_value": 6.78,
|
||||
"delta": 1.73,
|
||||
"tolerance": 1.0,
|
||||
"status": "method_variant",
|
||||
"variant": "mean_motion_seeghrochcha_variant"
|
||||
},
|
||||
{
|
||||
"component": "naisargika",
|
||||
"planet": "Sun",
|
||||
"unit": "Virupa",
|
||||
"published_value": 60.0,
|
||||
"local_value": 60.0,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "naisargika",
|
||||
"planet": "Moon",
|
||||
"unit": "Virupa",
|
||||
"published_value": 51.43,
|
||||
"local_value": 51.43,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "naisargika",
|
||||
"planet": "Mars",
|
||||
"unit": "Virupa",
|
||||
"published_value": 17.14,
|
||||
"local_value": 17.14,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "naisargika",
|
||||
"planet": "Mercury",
|
||||
"unit": "Virupa",
|
||||
"published_value": 25.71,
|
||||
"local_value": 25.71,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "naisargika",
|
||||
"planet": "Jupiter",
|
||||
"unit": "Virupa",
|
||||
"published_value": 34.29,
|
||||
"local_value": 34.29,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "naisargika",
|
||||
"planet": "Venus",
|
||||
"unit": "Virupa",
|
||||
"published_value": 42.86,
|
||||
"local_value": 42.86,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "naisargika",
|
||||
"planet": "Saturn",
|
||||
"unit": "Virupa",
|
||||
"published_value": 8.57,
|
||||
"local_value": 8.57,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "drik",
|
||||
"planet": "Sun",
|
||||
"unit": "Virupa",
|
||||
"published_value": 11.24,
|
||||
"local_value": 11.25,
|
||||
"delta": 0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "drik",
|
||||
"planet": "Moon",
|
||||
"unit": "Virupa",
|
||||
"published_value": -0.32,
|
||||
"local_value": -0.33,
|
||||
"delta": -0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "drik",
|
||||
"planet": "Mars",
|
||||
"unit": "Virupa",
|
||||
"published_value": -5.1,
|
||||
"local_value": -5.1,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "drik",
|
||||
"planet": "Mercury",
|
||||
"unit": "Virupa",
|
||||
"published_value": 4.29,
|
||||
"local_value": 4.29,
|
||||
"delta": 0.0,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "drik",
|
||||
"planet": "Jupiter",
|
||||
"unit": "Virupa",
|
||||
"published_value": 4.32,
|
||||
"local_value": 4.31,
|
||||
"delta": -0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "drik",
|
||||
"planet": "Venus",
|
||||
"unit": "Virupa",
|
||||
"published_value": -2.86,
|
||||
"local_value": -2.85,
|
||||
"delta": 0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
},
|
||||
{
|
||||
"component": "drik",
|
||||
"planet": "Saturn",
|
||||
"unit": "Virupa",
|
||||
"published_value": 5.82,
|
||||
"local_value": 5.83,
|
||||
"delta": 0.01,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance",
|
||||
"variant": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"boundary": "Multi-case replay and independent ephemeris reduce implementation risk; they do not arbitrate method variants without external numeric worked examples.",
|
||||
"independent_ephemeris_status": "ready",
|
||||
"multi_case_replay_status": "ready",
|
||||
"promotion_allowed": false,
|
||||
"public_case_count": 5,
|
||||
"required_next_evidence": [
|
||||
"published component-level Shadbala worked examples for every disputed component",
|
||||
"published BAV contributor-table example with per-sign rows",
|
||||
"formula-source citation for each Xalen/local method branch"
|
||||
],
|
||||
"scope": "xalen_formula_arbitration_gate",
|
||||
"truth_status": "blocked",
|
||||
"unresolved_variant_count": 46
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"candidate_window_policy": "Return ranked candidate days/months with signals and confidence caps; do not label them verified predictions until blind negative holdout passes.",
|
||||
"claim_status": "exploratory_unvalidated",
|
||||
"production_tuning_allowed": false,
|
||||
"required_label_contract": {
|
||||
"explicit_non_event_intervals": true,
|
||||
"independent_human_reviewed": true,
|
||||
"positive_and_negative_split_locked_before_scoring": true,
|
||||
"unobserved_before_preregistration": true
|
||||
},
|
||||
"scope": "timing_negative_holdout_source_audit",
|
||||
"sources": [
|
||||
{
|
||||
"blockers": [
|
||||
"missing_explicit_non_event_intervals",
|
||||
"not_independently_human_reviewed",
|
||||
"observed_before_preregistration"
|
||||
],
|
||||
"explicit_non_event_intervals": false,
|
||||
"independent_human_reviewed": false,
|
||||
"name": "Wikidata/EventKG/BiographyNet derived timelines",
|
||||
"notes": "Useful for positive event dates; missing events are not non-event labels.",
|
||||
"observed_before_preregistration": true,
|
||||
"positive_events": true,
|
||||
"usable_for_promotion": false
|
||||
},
|
||||
{
|
||||
"blockers": [
|
||||
"not_independently_human_reviewed",
|
||||
"observed_before_preregistration"
|
||||
],
|
||||
"explicit_non_event_intervals": true,
|
||||
"independent_human_reviewed": false,
|
||||
"name": "existing 40 control dates",
|
||||
"notes": "May remain diagnostic only; cannot tune or promote claims.",
|
||||
"observed_before_preregistration": true,
|
||||
"positive_events": false,
|
||||
"usable_for_promotion": false
|
||||
}
|
||||
],
|
||||
"timing_precision": "candidate_day_window"
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Probe jyotishyamitra as an independent oracle without copying implementation."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
|
||||
VERSION = "1.4.0"
|
||||
COMMIT = "86f7eb610a66b06b3f0817d2c53355bec8b3bf8d"
|
||||
LICENSE = "MIT"
|
||||
RETURNVAL = "ASTRODATA_DICTIONARY"
|
||||
|
||||
|
||||
def _sha256_bytes(data: bytes) -> str:
|
||||
return hashlib.sha256(data).hexdigest()
|
||||
|
||||
|
||||
def _stable_json(data: object) -> str:
|
||||
return json.dumps(data, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
|
||||
|
||||
|
||||
def wheel_metadata(wheel_path: Path) -> dict:
|
||||
with zipfile.ZipFile(wheel_path) as zf:
|
||||
metadata_name = next(name for name in zf.namelist() if name.endswith(".dist-info/METADATA"))
|
||||
wheel_name = next(name for name in zf.namelist() if name.endswith(".dist-info/WHEEL"))
|
||||
license_name = next((name for name in zf.namelist() if name.endswith(".dist-info/licenses/LICENSE")), None)
|
||||
metadata_text = zf.read(metadata_name).decode("utf-8", "replace")
|
||||
wheel_text = zf.read(wheel_name).decode("utf-8", "replace")
|
||||
license_text = zf.read(license_name).decode("utf-8", "replace") if license_name else ""
|
||||
fields = {}
|
||||
for line in metadata_text.splitlines():
|
||||
if ": " in line:
|
||||
key, value = line.split(": ", 1)
|
||||
fields.setdefault(key, value)
|
||||
tags = [line.split(": ", 1)[1] for line in wheel_text.splitlines() if line.startswith("Tag: ")]
|
||||
return {
|
||||
"metadata_name": metadata_name,
|
||||
"wheel_name": wheel_name,
|
||||
"name": fields.get("Name"),
|
||||
"version": fields.get("Version"),
|
||||
"license": fields.get("License"),
|
||||
"license_file_name": license_name,
|
||||
"license_file_sha256": _sha256_bytes(license_text.encode("utf-8")) if license_text else None,
|
||||
"license_file_spdx_inferred": "MIT" if "MIT License" in license_text else None,
|
||||
"requires_python": fields.get("Requires-Python"),
|
||||
"summary": fields.get("Summary"),
|
||||
"wheel_tags": tags,
|
||||
"metadata_sha256": _sha256_bytes(metadata_text.encode("utf-8")),
|
||||
"wheel_record_sha256": _sha256_bytes(wheel_text.encode("utf-8")),
|
||||
}
|
||||
|
||||
|
||||
def canonical_request(case: dict) -> dict:
|
||||
birth = case["birth"]
|
||||
return {
|
||||
"name": case.get("name", "public_case"),
|
||||
"gender": case.get("gender", "male"),
|
||||
"place": case.get("place", "unknown"),
|
||||
"longitude": case["longitude"],
|
||||
"latitude": case["latitude"],
|
||||
"timezone": case["timezone"],
|
||||
"birth": {
|
||||
"year": birth["year"],
|
||||
"month": birth["month"],
|
||||
"day": birth["day"],
|
||||
"hour": birth["hour"],
|
||||
"minute": birth["minute"],
|
||||
"second": birth.get("second", 0),
|
||||
},
|
||||
"ayanamsa": case.get("ayanamsa", "package_default"),
|
||||
"node_mode": case.get("node_mode", "package_default"),
|
||||
"returnval": RETURNVAL,
|
||||
}
|
||||
|
||||
|
||||
def schema_fingerprint(raw: object) -> dict:
|
||||
paths = []
|
||||
|
||||
def walk(value: object, prefix: str = "$") -> None:
|
||||
if isinstance(value, dict):
|
||||
for key in sorted(value):
|
||||
walk(value[key], f"{prefix}.{key}")
|
||||
elif isinstance(value, list):
|
||||
paths.append(f"{prefix}[]")
|
||||
if value:
|
||||
walk(value[0], f"{prefix}[]")
|
||||
else:
|
||||
paths.append(f"{prefix}:{type(value).__name__}")
|
||||
|
||||
walk(raw)
|
||||
joined = "\n".join(paths)
|
||||
return {"path_count": len(paths), "sha256": _sha256_bytes(joined.encode("utf-8")), "sample_paths": paths[:80]}
|
||||
|
||||
|
||||
def normalize_raw(raw: object) -> object:
|
||||
data = copy.deepcopy(raw)
|
||||
try:
|
||||
data["Dashas"]["Vimshottari"]["current"]["date"] = "<volatile_run_time>"
|
||||
except (TypeError, KeyError):
|
||||
pass
|
||||
return data
|
||||
|
||||
|
||||
def run_installed_jyotishyamitra(case: dict) -> object:
|
||||
import importlib
|
||||
|
||||
jm = importlib.import_module("jyotishyamitra")
|
||||
request = canonical_request(case)
|
||||
birth = request["birth"]
|
||||
data = jm.input_birthdata(
|
||||
name=request["name"],
|
||||
gender=request["gender"],
|
||||
place=request["place"],
|
||||
longitude=str(request["longitude"]),
|
||||
lattitude=str(request["latitude"]),
|
||||
timezone=str(request["timezone"]),
|
||||
year=str(birth["year"]),
|
||||
month=str(birth["month"]),
|
||||
day=str(birth["day"]),
|
||||
hour=str(birth["hour"]),
|
||||
min=str(birth["minute"]),
|
||||
sec=str(birth.get("second", 0)),
|
||||
)
|
||||
validation = jm.validate_birthdata()
|
||||
if validation != "SUCCESS":
|
||||
return {"status": "INPUT_ERROR", "validation": validation, "input": data}
|
||||
return jm.generate_astrologicalData(jm.get_birthdata(), returnval=request["returnval"])
|
||||
|
||||
|
||||
def run_isolated(wheel_path: Path, case: dict) -> dict:
|
||||
with TemporaryDirectory() as tmp:
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "pip", "install", "--no-deps", "--target", tmp, str(wheel_path)],
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
)
|
||||
code = (
|
||||
"import json,sys;"
|
||||
"sys.path.insert(0, sys.argv[1]);"
|
||||
"from scripts.jyotishyamitra_adapter_probe import run_installed_jyotishyamitra;"
|
||||
"case=json.loads(sys.stdin.read());"
|
||||
"print(json.dumps(run_installed_jyotishyamitra(case), ensure_ascii=False, sort_keys=True))"
|
||||
)
|
||||
env = {**os.environ, "PYTHONPATH": str(Path.cwd())}
|
||||
done = subprocess.run(
|
||||
[sys.executable, "-c", code, tmp],
|
||||
input=_stable_json(case),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
env=env,
|
||||
check=False,
|
||||
)
|
||||
raw = json.loads(done.stdout) if done.returncode == 0 and done.stdout.strip().startswith(("{", "[", '"')) else done.stdout.strip()
|
||||
return {
|
||||
"install_path": tmp,
|
||||
"returncode": done.returncode,
|
||||
"stderr": done.stderr.strip(),
|
||||
"raw": raw,
|
||||
}
|
||||
|
||||
|
||||
def extract_fields(raw: dict) -> dict:
|
||||
keys = ("D1", "D2", "D4", "D9", "D10", "ashtakavarga", "shadbala", "vimshottari")
|
||||
lowered = {str(k).lower(): k for k in raw}
|
||||
out = {}
|
||||
for key in keys:
|
||||
source = lowered.get(key.lower())
|
||||
if source is not None:
|
||||
out[key] = raw[source]
|
||||
return out
|
||||
|
||||
|
||||
def compare_with_existing_oracles(jyotishyamitra: dict, local: dict, xalen: dict) -> dict:
|
||||
rows = []
|
||||
counts = {"local": 0, "xalen": 0}
|
||||
for section, fields in jyotishyamitra.items():
|
||||
if not isinstance(fields, dict):
|
||||
continue
|
||||
for field, value in fields.items():
|
||||
local_value = (local.get(section) or {}).get(field)
|
||||
xalen_value = (xalen.get(section) or {}).get(field)
|
||||
local_match = value == local_value
|
||||
xalen_match = value == xalen_value
|
||||
counts["local"] += int(local_match)
|
||||
counts["xalen"] += int(xalen_match)
|
||||
rows.append(
|
||||
{
|
||||
"section": section,
|
||||
"field": field,
|
||||
"jyotishyamitra_value": value,
|
||||
"local_value": local_value,
|
||||
"xalen_value": xalen_value,
|
||||
"local_status": "match" if local_match else "mismatch",
|
||||
"xalen_status": "match" if xalen_match else "mismatch",
|
||||
}
|
||||
)
|
||||
return {
|
||||
"scope": "jyotishyamitra_field_comparison",
|
||||
"row_count": len(rows),
|
||||
"match_counts": counts,
|
||||
"promotion_allowed": False,
|
||||
"truth_policy": "independent_observation_not_truth",
|
||||
"rows": rows,
|
||||
}
|
||||
|
||||
|
||||
def build_report(
|
||||
wheel_path: Path,
|
||||
commit: str = COMMIT,
|
||||
raw: dict | None = None,
|
||||
comparison: dict | None = None,
|
||||
request: dict | None = None,
|
||||
isolated_run: dict | None = None,
|
||||
) -> dict:
|
||||
if not wheel_path.exists():
|
||||
return {
|
||||
"scope": "jyotishyamitra_pinned_adapter_probe",
|
||||
"oracle": "jyotishyamitra",
|
||||
"version": VERSION,
|
||||
"source_commit": commit,
|
||||
"license": LICENSE,
|
||||
"wheel_path": str(wheel_path),
|
||||
"status": "blocked",
|
||||
"blocked_reason": "fixture_missing",
|
||||
"truth_policy": "independent_observation_not_truth",
|
||||
"promotion_allowed": False,
|
||||
"boundary": "Wheel fixture is required; adapter must not download at test/runtime or use fake zip evidence.",
|
||||
}
|
||||
raw = raw or {}
|
||||
normalized = normalize_raw(raw)
|
||||
wheel_hash = _sha256_bytes(wheel_path.read_bytes()) if wheel_path.exists() else None
|
||||
meta = wheel_metadata(wheel_path) if wheel_path.exists() else {}
|
||||
return {
|
||||
"scope": "jyotishyamitra_pinned_adapter_probe",
|
||||
"oracle": "jyotishyamitra",
|
||||
"version": VERSION,
|
||||
"source_commit": commit,
|
||||
"source_url": f"https://github.com/VicharaVandana/jyotishyamitra/commit/{commit}",
|
||||
"package_url": "https://pypi.org/project/jyotishyamitra/1.4.0/",
|
||||
"license": LICENSE,
|
||||
"package_metadata": meta,
|
||||
"python_runtime": {
|
||||
"executable": sys.executable,
|
||||
"version": sys.version.split()[0],
|
||||
"wheel_tags": meta.get("wheel_tags", []),
|
||||
},
|
||||
"canonical_request": request or {},
|
||||
"isolated_subprocess": {
|
||||
"used": isolated_run is not None,
|
||||
"returncode": None if isolated_run is None else isolated_run["returncode"],
|
||||
"temporary_install_path": None if isolated_run is None else isolated_run["install_path"],
|
||||
"stderr": None if isolated_run is None else isolated_run["stderr"],
|
||||
},
|
||||
"wheel_path": str(wheel_path),
|
||||
"wheel_sha256": wheel_hash,
|
||||
"raw_sha256": _sha256_bytes(_stable_json(raw).encode("utf-8")),
|
||||
"normalized_raw_sha256": _sha256_bytes(_stable_json(normalized).encode("utf-8")),
|
||||
"normalization": {
|
||||
"volatile_paths": ["$.Dashas.Vimshottari.current.date"],
|
||||
"purpose": "remove run timestamp before replay comparison",
|
||||
},
|
||||
"schema_fingerprint": schema_fingerprint(raw),
|
||||
"raw": raw,
|
||||
"comparison": comparison or {},
|
||||
"truth_policy": "independent_observation_not_truth",
|
||||
"promotion_allowed": False,
|
||||
"status": "stable_raw_ready_as_independent_observation" if raw and not (isinstance(raw, dict) and raw.get("status") == "INPUT_ERROR") else "metadata_only_or_input_blocked",
|
||||
"boundary": "Adapter calls the installed MIT package as an oracle; it does not copy implementation or promote conclusions.",
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--wheel", type=Path, default=Path("/tmp/jyotishyamitra_probe/jyotishyamitra-1.4.0-py3-none-any.whl"))
|
||||
parser.add_argument("--case-json", type=Path)
|
||||
parser.add_argument("--output", type=Path)
|
||||
args = parser.parse_args()
|
||||
raw = {}
|
||||
request = {}
|
||||
isolated = None
|
||||
if args.case_json:
|
||||
case = json.loads(args.case_json.read_text(encoding="utf-8"))
|
||||
request = canonical_request(case)
|
||||
isolated = run_isolated(args.wheel, case)
|
||||
raw = isolated["raw"]
|
||||
report = build_report(args.wheel, raw=raw, request=request, isolated_run=isolated)
|
||||
text = json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + "\n"
|
||||
if args.output:
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(text, encoding="utf-8")
|
||||
sys.stdout.write(text)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Audit whether candidate sources can promote day/month timing claims."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
DEFAULT_SOURCES = [
|
||||
{
|
||||
"name": "Wikidata/EventKG/BiographyNet derived timelines",
|
||||
"positive_events": True,
|
||||
"explicit_non_event_intervals": False,
|
||||
"independent_human_reviewed": False,
|
||||
"observed_before_preregistration": True,
|
||||
"notes": "Useful for positive event dates; missing events are not non-event labels.",
|
||||
},
|
||||
{
|
||||
"name": "existing 40 control dates",
|
||||
"positive_events": False,
|
||||
"explicit_non_event_intervals": True,
|
||||
"independent_human_reviewed": False,
|
||||
"observed_before_preregistration": True,
|
||||
"notes": "May remain diagnostic only; cannot tune or promote claims.",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def evaluate_source(source: dict) -> dict:
|
||||
blockers = []
|
||||
if not source.get("explicit_non_event_intervals"):
|
||||
blockers.append("missing_explicit_non_event_intervals")
|
||||
if not source.get("independent_human_reviewed"):
|
||||
blockers.append("not_independently_human_reviewed")
|
||||
if source.get("observed_before_preregistration"):
|
||||
blockers.append("observed_before_preregistration")
|
||||
return {
|
||||
**source,
|
||||
"usable_for_promotion": not blockers,
|
||||
"blockers": blockers,
|
||||
}
|
||||
|
||||
|
||||
def build_report(sources: list[dict] | None = None) -> dict:
|
||||
rows = [evaluate_source(source) for source in (sources or DEFAULT_SOURCES)]
|
||||
usable = [row for row in rows if row["usable_for_promotion"]]
|
||||
return {
|
||||
"scope": "timing_negative_holdout_source_audit",
|
||||
"claim_status": "exploratory_unvalidated" if not usable else "ready_for_blind_holdout",
|
||||
"timing_precision": "candidate_day_window",
|
||||
"production_tuning_allowed": False if not usable else True,
|
||||
"candidate_window_policy": (
|
||||
"Return ranked candidate days/months with signals and confidence caps; "
|
||||
"do not label them verified predictions until blind negative holdout passes."
|
||||
),
|
||||
"required_label_contract": {
|
||||
"explicit_non_event_intervals": True,
|
||||
"independent_human_reviewed": True,
|
||||
"unobserved_before_preregistration": True,
|
||||
"positive_and_negative_split_locked_before_scoring": True,
|
||||
},
|
||||
"sources": rows,
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--source-json", type=Path)
|
||||
parser.add_argument("--output", type=Path)
|
||||
args = parser.parse_args()
|
||||
sources = None
|
||||
if args.source_json:
|
||||
sources = json.loads(args.source_json.read_text(encoding="utf-8"))["sources"]
|
||||
report = build_report(sources)
|
||||
text = json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + "\n"
|
||||
if args.output:
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(text, encoding="utf-8")
|
||||
sys.stdout.write(text)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Archive reproducible VedAstro package identity and hosted-version gap."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from urllib.request import urlopen
|
||||
|
||||
|
||||
REGISTRATION_URL = (
|
||||
"https://api.nuget.org/v3/registration5-semver1/"
|
||||
"vedastro.library/{version}.json"
|
||||
)
|
||||
|
||||
|
||||
def _json_url(url: str, timeout: float) -> dict:
|
||||
with urlopen(url, timeout=timeout) as response: # noqa: S310 - fixed public NuGet URL.
|
||||
return json.loads(response.read().decode("utf-8"))
|
||||
|
||||
|
||||
def build_archive(version: str = "1.2.0", timeout: float = 20.0) -> dict:
|
||||
registration = _json_url(REGISTRATION_URL.format(version=version), timeout)
|
||||
catalog_url = registration["catalogEntry"]
|
||||
catalog = _json_url(catalog_url, timeout)
|
||||
deps = []
|
||||
for group in catalog.get("dependencyGroups") or []:
|
||||
target = group.get("targetFramework")
|
||||
for dep in group.get("dependencies") or []:
|
||||
deps.append(
|
||||
{
|
||||
"target_framework": target,
|
||||
"id": dep["id"],
|
||||
"range": dep["range"],
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"scope": "vedastro_reproducible_identity_archive",
|
||||
"package": "VedAstro.Library",
|
||||
"version": version,
|
||||
"nuget_registration_url": REGISTRATION_URL.format(version=version),
|
||||
"nuget_catalog_url": catalog_url,
|
||||
"package_content_url": registration["packageContent"],
|
||||
"package_hash_algorithm": catalog.get("packageHashAlgorithm"),
|
||||
"package_hash": catalog.get("packageHash"),
|
||||
"package_size": catalog.get("packageSize"),
|
||||
"published": catalog.get("published") or registration.get("published"),
|
||||
"catalog_commit_id": catalog.get("catalog:commitId"),
|
||||
"catalog_commit_timestamp": catalog.get("catalog:commitTimeStamp"),
|
||||
"license": catalog.get("licenseExpression"),
|
||||
"project_url": catalog.get("projectUrl"),
|
||||
"dependencies": deps,
|
||||
"self_host_candidate_status": "reproducible_package_identity_archived",
|
||||
"hosted_api_status": "blocked",
|
||||
"hosted_api_blocker": (
|
||||
"api.vedastro.org does not expose a verified build commit, package hash, "
|
||||
"DLL hash, assembly version, container digest, or method-semantics contract."
|
||||
),
|
||||
"boundary": (
|
||||
"This archive fixes a NuGet self-host candidate identity only; it does not "
|
||||
"prove the hosted API is running this package or the same method semantics."
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--version", default="1.2.0")
|
||||
parser.add_argument("--timeout", type=float, default=20.0)
|
||||
parser.add_argument("--output", type=Path)
|
||||
args = parser.parse_args()
|
||||
report = build_archive(args.version, args.timeout)
|
||||
text = json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + "\n"
|
||||
if args.output:
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(text, encoding="utf-8")
|
||||
sys.stdout.write(text)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Compare the native Shadbala chain with VP Jain's published worked example."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
PLANETS = ("Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn")
|
||||
EXPECTED = {
|
||||
"sthana": (172.04, 77.17, 184.94, 238.16, 152.98, 198.08, 206.31),
|
||||
"dig": (6.59, 12.22, 20.99, 31.97, 31.99, 53.29, 26.67),
|
||||
"kala": (81.80, 205.85, 158.08, 210.68, 144.22, 135.89, 139.56),
|
||||
"chesta": (0.0, 0.0, 20.93, 28.76, 8.43, 28.18, 5.05),
|
||||
"naisargika": (60.0, 51.43, 17.14, 25.71, 34.29, 42.86, 8.57),
|
||||
"drik": (11.24, -0.32, -5.10, 4.29, 4.32, -2.86, 5.82),
|
||||
}
|
||||
LOCAL_KEYS = {
|
||||
"sthana": ("sthana_bala", "total"),
|
||||
"dig": ("dig_bala",),
|
||||
"kala": ("kala_bala", "total"),
|
||||
"chesta": ("chesta_bala",),
|
||||
"naisargika": ("naisargika_bala",),
|
||||
"drik": ("drik_bala",),
|
||||
}
|
||||
|
||||
|
||||
def _native_output() -> dict:
|
||||
command = [
|
||||
sys.executable, str(ROOT / "scripts" / "jyotish_engine.py"), "shadbala",
|
||||
"--year", "1981", "--month", "9", "--day", "13",
|
||||
"--hour", "1", "--minute", "30", "--lat", "28.65",
|
||||
"--lon", "77.2166666667", "--tz", "5.5", "--ayanamsa", "lahiri",
|
||||
]
|
||||
return json.loads(subprocess.check_output(command, cwd=ROOT, text=True))
|
||||
|
||||
|
||||
def _value(row: dict, path: tuple[str, ...]) -> float:
|
||||
value = row
|
||||
for key in path:
|
||||
value = value[key]
|
||||
return float(value)
|
||||
|
||||
|
||||
def _variant(component: str, planet: str) -> str:
|
||||
if component == "sthana":
|
||||
return "moolatrikona_degree_range_vs_whole_sign"
|
||||
if planet in {"Sun", "Moon"}:
|
||||
return "luminary_chesta_policy"
|
||||
return "mean_motion_seeghrochcha_variant"
|
||||
|
||||
|
||||
def build_report() -> dict:
|
||||
actual = _native_output()["planets"]
|
||||
rows = []
|
||||
for component, expected_values in EXPECTED.items():
|
||||
for planet, expected in zip(PLANETS, expected_values):
|
||||
local = _value(actual[planet], LOCAL_KEYS[component])
|
||||
delta = round(local - expected, 4)
|
||||
matched = abs(delta) <= 1.0
|
||||
rows.append({
|
||||
"component": component,
|
||||
"planet": planet,
|
||||
"unit": "Virupa",
|
||||
"published_value": expected,
|
||||
"local_value": local,
|
||||
"delta": delta,
|
||||
"tolerance": 1.0,
|
||||
"status": "within_tolerance" if matched else "method_variant",
|
||||
"variant": None if matched else _variant(component, planet),
|
||||
})
|
||||
matched = sum(row["status"] == "within_tolerance" for row in rows)
|
||||
return {
|
||||
"case": {
|
||||
"name": "VP Jain published Shadbala example",
|
||||
"birth": "1981-09-13T01:30:00+05:30",
|
||||
"latitude": 28.65,
|
||||
"longitude": 77.2166666667,
|
||||
"ayanamsa": "Lahiri",
|
||||
},
|
||||
"source": {
|
||||
"upstream": "PyJHora 4.8.7 pvr_tests.py::shadbala_VPJainBook_tests",
|
||||
"upstream_issue": "https://github.com/naturalstupid/PyJHora/issues/17",
|
||||
"license_boundary": "Numeric published-example expectations only; no AGPL implementation copied.",
|
||||
},
|
||||
"summary": {
|
||||
"row_count": len(rows),
|
||||
"classified_count": len(rows),
|
||||
"within_tolerance_count": matched,
|
||||
"method_variant_count": len(rows) - matched,
|
||||
"absolute_parity": False,
|
||||
},
|
||||
"rows": rows,
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output = ROOT / "references" / "oracle" / "vp_jain_shadbala_component_benchmark_2026_07_17.json"
|
||||
output.write_text(json.dumps(build_report(), ensure_ascii=False, indent=2) + "\n")
|
||||
print(output)
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Gate Xalen Shadbala/Ashtakavarga variants against external arbitration needs."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def build_report(attribution_path: Path, public_batch_path: Path, ephemeris_path: Path) -> dict:
|
||||
attribution = json.loads(attribution_path.read_text(encoding="utf-8"))
|
||||
public_batch = json.loads(public_batch_path.read_text(encoding="utf-8"))
|
||||
ephemeris = json.loads(ephemeris_path.read_text(encoding="utf-8"))
|
||||
unresolved = [
|
||||
row for row in attribution["rows"]
|
||||
if row.get("truth_status") in {
|
||||
"method_variant_unresolved",
|
||||
"requires_external_worked_example_per_contributor",
|
||||
"defer_until_components_arbitrated",
|
||||
}
|
||||
]
|
||||
enough_cases = public_batch.get("case_count", 0) >= 5
|
||||
independent_ephemeris_ok = (
|
||||
ephemeris.get("maximum_absolute_longitude_delta_deg", 999) <= 0.01
|
||||
and ephemeris.get("varga_difference_count") == 0
|
||||
)
|
||||
return {
|
||||
"scope": "xalen_formula_arbitration_gate",
|
||||
"public_case_count": public_batch.get("case_count", 0),
|
||||
"multi_case_replay_status": "ready" if enough_cases else "partial",
|
||||
"independent_ephemeris_status": "ready" if independent_ephemeris_ok else "partial",
|
||||
"unresolved_variant_count": len(unresolved),
|
||||
"truth_status": "blocked" if unresolved else "ready",
|
||||
"promotion_allowed": not unresolved and enough_cases and independent_ephemeris_ok,
|
||||
"required_next_evidence": [
|
||||
"published component-level Shadbala worked examples for every disputed component",
|
||||
"published BAV contributor-table example with per-sign rows",
|
||||
"formula-source citation for each Xalen/local method branch",
|
||||
],
|
||||
"boundary": (
|
||||
"Multi-case replay and independent ephemeris reduce implementation risk; "
|
||||
"they do not arbitrate method variants without external numeric worked examples."
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"--attribution",
|
||||
type=Path,
|
||||
default=Path("references/oracle/xalen_formula_unit_attribution_2026_07_17.json"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--public-batch",
|
||||
type=Path,
|
||||
default=Path("references/oracle/xalen_public_case_batch_2026_07_17.json"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ephemeris",
|
||||
type=Path,
|
||||
default=Path("references/oracle/xalen_ephemeris_mode_comparison_2026_07_17.json"),
|
||||
)
|
||||
parser.add_argument("--output", type=Path)
|
||||
args = parser.parse_args()
|
||||
report = build_report(args.attribution, args.public_batch, args.ephemeris)
|
||||
text = json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + "\n"
|
||||
if args.output:
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(text, encoding="utf-8")
|
||||
sys.stdout.write(text)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,95 @@
|
||||
from pathlib import Path
|
||||
|
||||
from scripts.jyotishyamitra_adapter_probe import (
|
||||
build_report,
|
||||
canonical_request,
|
||||
compare_with_existing_oracles,
|
||||
normalize_raw,
|
||||
schema_fingerprint,
|
||||
)
|
||||
|
||||
|
||||
WHEEL = Path("/tmp/jyotishyamitra_probe/jyotishyamitra-1.4.0-py3-none-any.whl")
|
||||
WHEEL_SHA256 = "4f1a16facfa86ef01cb44de505c6de2e66b2f8d2c8b5e125c090e3f8485c6a9d"
|
||||
|
||||
|
||||
def test_jyotishyamitra_probe_contract_uses_pinned_identity_fixture(tmp_path: Path) -> None:
|
||||
wheel = WHEEL
|
||||
assert wheel.exists(), "fixture_missing: run pinned wheel download outside CI; tests must not fetch network"
|
||||
report = build_report(
|
||||
wheel_path=wheel,
|
||||
commit="86f7eb610a66b06b3f0817d2c53355bec8b3bf8d",
|
||||
raw={"D1": {"Sun": "Aquarius"}, "metadata": {"ayanamsa": "Lahiri"}},
|
||||
)
|
||||
|
||||
assert report["oracle"] == "jyotishyamitra"
|
||||
assert report["license"] == "MIT"
|
||||
assert report["version"] == "1.4.0"
|
||||
assert report["source_commit"] == "86f7eb610a66b06b3f0817d2c53355bec8b3bf8d"
|
||||
assert report["wheel_sha256"]
|
||||
assert report["wheel_sha256"] == WHEEL_SHA256
|
||||
assert report["raw_sha256"]
|
||||
assert report["normalized_raw_sha256"]
|
||||
assert report["package_metadata"]["version"] == "1.4.0"
|
||||
assert report["package_metadata"]["requires_python"] == ">=3.7"
|
||||
assert report["package_metadata"]["license"] is None
|
||||
assert report["package_metadata"]["license_file_spdx_inferred"] == "MIT"
|
||||
assert report["python_runtime"]["version"]
|
||||
assert report["schema_fingerprint"]["sha256"]
|
||||
assert report["isolated_subprocess"]["used"] is False
|
||||
assert report["truth_policy"] == "independent_observation_not_truth"
|
||||
|
||||
|
||||
def test_jyotishyamitra_missing_wheel_is_explicitly_blocked(tmp_path: Path) -> None:
|
||||
report = build_report(tmp_path / "missing.whl")
|
||||
|
||||
assert report["status"] == "blocked"
|
||||
assert report["blocked_reason"] == "fixture_missing"
|
||||
assert report["promotion_allowed"] is False
|
||||
|
||||
|
||||
def test_jyotishyamitra_canonical_request_records_defaults() -> None:
|
||||
request = canonical_request(
|
||||
{
|
||||
"name": "Steve Jobs",
|
||||
"gender": "male",
|
||||
"place": "San Francisco",
|
||||
"longitude": -122.4194,
|
||||
"latitude": 37.7749,
|
||||
"timezone": -8.0,
|
||||
"birth": {"year": 1955, "month": 2, "day": 24, "hour": 19, "minute": 15},
|
||||
}
|
||||
)
|
||||
|
||||
assert request["ayanamsa"] == "package_default"
|
||||
assert request["node_mode"] == "package_default"
|
||||
assert request["returnval"] == "ASTRODATA_DICTIONARY"
|
||||
assert request["birth"]["second"] == 0
|
||||
|
||||
|
||||
def test_jyotishyamitra_schema_fingerprint_is_stable() -> None:
|
||||
fp = schema_fingerprint({"D1": {"Sun": "Aquarius"}, "scores": [1, 2]})
|
||||
|
||||
assert fp["path_count"] == 3
|
||||
assert fp["sha256"]
|
||||
assert "$.D1.Sun:str" in fp["sample_paths"]
|
||||
|
||||
|
||||
def test_jyotishyamitra_normalizes_volatile_current_dasha_timestamp() -> None:
|
||||
a = {"Dashas": {"Vimshottari": {"current": {"date": "run-a", "lord": "Sun"}}}}
|
||||
b = {"Dashas": {"Vimshottari": {"current": {"date": "run-b", "lord": "Sun"}}}}
|
||||
|
||||
assert normalize_raw(a) == normalize_raw(b)
|
||||
|
||||
|
||||
def test_jyotishyamitra_field_comparison_is_observation_not_promotion() -> None:
|
||||
comparison = compare_with_existing_oracles(
|
||||
{"D1": {"Sun": "Aquarius"}, "D9": {"Moon": "Cancer"}},
|
||||
{"D1": {"Sun": "Aquarius"}, "D9": {"Moon": "Leo"}},
|
||||
{"D1": {"Sun": "Aquarius"}, "D9": {"Moon": "Cancer"}},
|
||||
)
|
||||
|
||||
assert comparison["row_count"] == 2
|
||||
assert comparison["match_counts"]["local"] == 1
|
||||
assert comparison["match_counts"]["xalen"] == 2
|
||||
assert comparison["promotion_allowed"] is False
|
||||
@@ -0,0 +1,38 @@
|
||||
from scripts.timing_negative_holdout_audit import build_report
|
||||
|
||||
|
||||
def test_timing_negative_holdout_blocks_positive_only_sources() -> None:
|
||||
report = build_report(
|
||||
[
|
||||
{
|
||||
"name": "positive-only public timeline",
|
||||
"positive_events": True,
|
||||
"explicit_non_event_intervals": False,
|
||||
"independent_human_reviewed": False,
|
||||
"observed_before_preregistration": False,
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
assert report["claim_status"] == "exploratory_unvalidated"
|
||||
assert report["production_tuning_allowed"] is False
|
||||
assert report["sources"][0]["usable_for_promotion"] is False
|
||||
assert "missing_explicit_non_event_intervals" in report["sources"][0]["blockers"]
|
||||
|
||||
|
||||
def test_timing_negative_holdout_can_only_promote_locked_independent_labels() -> None:
|
||||
report = build_report(
|
||||
[
|
||||
{
|
||||
"name": "locked blind label packet",
|
||||
"positive_events": True,
|
||||
"explicit_non_event_intervals": True,
|
||||
"independent_human_reviewed": True,
|
||||
"observed_before_preregistration": False,
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
assert report["claim_status"] == "ready_for_blind_holdout"
|
||||
assert report["production_tuning_allowed"] is True
|
||||
assert report["sources"][0]["blockers"] == []
|
||||
@@ -0,0 +1,38 @@
|
||||
from scripts.vedastro_identity_archive import build_archive
|
||||
|
||||
|
||||
def test_vedastro_identity_archive_records_self_host_identity(monkeypatch) -> None:
|
||||
fixtures = {
|
||||
"https://api.nuget.org/v3/registration5-semver1/vedastro.library/1.2.0.json": {
|
||||
"catalogEntry": "https://example.invalid/catalog.json",
|
||||
"packageContent": "https://example.invalid/pkg.nupkg",
|
||||
"published": "2023-03-22T22:22:01.81+00:00",
|
||||
},
|
||||
"https://example.invalid/catalog.json": {
|
||||
"packageHashAlgorithm": "SHA512",
|
||||
"packageHash": "hash",
|
||||
"packageSize": 230836,
|
||||
"published": "2023-03-22T22:22:01.81Z",
|
||||
"catalog:commitId": "commit",
|
||||
"catalog:commitTimeStamp": "2023-03-22T22:24:11.811524Z",
|
||||
"licenseExpression": "MIT",
|
||||
"projectUrl": "https://vedastro.org/",
|
||||
"dependencyGroups": [
|
||||
{
|
||||
"targetFramework": "net7.0",
|
||||
"dependencies": [{"id": "SwissEphNet", "range": "[2.8.0.2, )"}],
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
monkeypatch.setattr("scripts.vedastro_identity_archive._json_url", lambda url, timeout: fixtures[url])
|
||||
report = build_archive("1.2.0")
|
||||
|
||||
assert report["package_hash_algorithm"] == "SHA512"
|
||||
assert report["license"] == "MIT"
|
||||
assert report["self_host_candidate_status"] == "reproducible_package_identity_archived"
|
||||
assert report["hosted_api_status"] == "blocked"
|
||||
assert report["dependencies"] == [
|
||||
{"target_framework": "net7.0", "id": "SwissEphNet", "range": "[2.8.0.2, )"}
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
from scripts.vp_jain_shadbala_benchmark import build_report
|
||||
|
||||
|
||||
def test_vp_jain_published_component_benchmark_is_fully_classified() -> None:
|
||||
report = build_report()
|
||||
|
||||
assert report["case"]["name"] == "VP Jain published Shadbala example"
|
||||
assert report["summary"]["row_count"] == 42
|
||||
assert report["summary"]["classified_count"] == 42
|
||||
assert report["summary"]["within_tolerance_count"] == 34
|
||||
assert report["summary"]["method_variant_count"] == 8
|
||||
|
||||
|
||||
def test_vp_jain_benchmark_keeps_known_method_variants_explicit() -> None:
|
||||
rows = build_report()["rows"]
|
||||
variants = {(row["component"], row["planet"]): row for row in rows if row["status"] != "within_tolerance"}
|
||||
|
||||
assert set(variants) == {
|
||||
("sthana", "Sun"),
|
||||
("sthana", "Mercury"),
|
||||
("chesta", "Sun"),
|
||||
("chesta", "Moon"),
|
||||
("chesta", "Mars"),
|
||||
("chesta", "Mercury"),
|
||||
("chesta", "Jupiter"),
|
||||
("chesta", "Saturn"),
|
||||
}
|
||||
assert variants[("sthana", "Sun")]["variant"] == "moolatrikona_degree_range_vs_whole_sign"
|
||||
assert variants[("chesta", "Moon")]["variant"] == "luminary_chesta_policy"
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import json
|
||||
|
||||
from scripts.xalen_arbitration_gate import build_report
|
||||
|
||||
|
||||
def test_xalen_arbitration_gate_blocks_unresolved_method_variants(tmp_path) -> None:
|
||||
attribution = tmp_path / "attr.json"
|
||||
public_batch = tmp_path / "batch.json"
|
||||
ephemeris = tmp_path / "ephem.json"
|
||||
attribution.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"rows": [
|
||||
{
|
||||
"field": "Sun.chesta",
|
||||
"truth_status": "method_variant_unresolved",
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
public_batch.write_text(json.dumps({"case_count": 5}), encoding="utf-8")
|
||||
ephemeris.write_text(
|
||||
json.dumps({"maximum_absolute_longitude_delta_deg": 0.001, "varga_difference_count": 0}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
report = build_report(attribution, public_batch, ephemeris)
|
||||
|
||||
assert report["multi_case_replay_status"] == "ready"
|
||||
assert report["independent_ephemeris_status"] == "ready"
|
||||
assert report["truth_status"] == "blocked"
|
||||
assert report["promotion_allowed"] is False
|
||||
|
||||
|
||||
def test_xalen_arbitration_gate_allows_only_when_variants_are_arbitrated(tmp_path) -> None:
|
||||
attribution = tmp_path / "attr.json"
|
||||
public_batch = tmp_path / "batch.json"
|
||||
ephemeris = tmp_path / "ephem.json"
|
||||
attribution.write_text(json.dumps({"rows": [{"truth_status": "external_worked_example_match"}]}), encoding="utf-8")
|
||||
public_batch.write_text(json.dumps({"case_count": 5}), encoding="utf-8")
|
||||
ephemeris.write_text(
|
||||
json.dumps({"maximum_absolute_longitude_delta_deg": 0.001, "varga_difference_count": 0}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
report = build_report(attribution, public_batch, ephemeris)
|
||||
|
||||
assert report["truth_status"] == "ready"
|
||||
assert report["promotion_allowed"] is True
|
||||
Reference in New Issue
Block a user