feat: carry VedAstro raw archive manifest in evidence packets

This commit is contained in:
732642856
2026-07-08 21:15:04 +08:00
parent 09dcfb9bcc
commit beaabe4e6a
7 changed files with 36 additions and 0 deletions
+1
View File
@@ -51,6 +51,7 @@ For large architecture or release work, also read:
| ERR-018 | External engine blockers can be described verbally but not carried into diagnostics. | mitigated 2026-07-05 | `diagnose_external_engine_adapters.py` must expose VedAstro closure plan and PyJHora/JHora install/license/ephemeris boundary; keep `docs/research/external_engine_blocker_research_2026_07_05.md` current. |
| ERR-019 | WorkBuddy/cloud/local acceptance summaries can invent pass counts, stale asset counts, non-existent error docs, or wrong dasha windows. | mitigated 2026-07-06 | Read `docs/research/user_invocation_acceptance_error_log_2026_07_06.md`; run `scripts/user_invocation_acceptance_check.py` and `tests/test_user_invocation_acceptance_contract.py` before accepting ordinary-user skill invocation validation claims. |
| ERR-020 | VedAstro official raw responses can be archived but hard to audit if no manifest/API listing exposes them. | mitigated 2026-07-08 | Keep `list_official_raw_response_archives()` and `GET /api/vedastro_gateway/archives`; tests must prove archived official raw responses are enumerable. |
| ERR-021 | VedAstro raw archive manifests can exist outside the high-rigor evidence packet, leaving final reports unable to prove whether official raw evidence was archived. | mitigated 2026-07-08 | Keep `vedastro_official_raw_archive_manifest` in `machine_evidence_packet.sections` for API and MCP strict workflows. |
## Fragment Sweep Command Set
+2
View File
@@ -4254,11 +4254,13 @@ def strict_workflow(
handler = JyotishAPIHandler.__new__(JyotishAPIHandler)
vedastro_official = handler._high_rigor_vedastro_official_summary(chart)
vedastro_archive_manifest = handler._compute_vedastro_gateway_archives()
interpretation_coverage = handler._interpretation_source_runtime_coverage(chart)
machine_evidence_packet = _UNIFIED_CONSULTATION_ORCHESTRATOR.machine_evidence_packet(
chart=chart,
route_packet=result.get("routing") if isinstance(result.get("routing"), dict) else route_packet,
vedastro_official=vedastro_official,
vedastro_archive_manifest=vedastro_archive_manifest,
)
real_case_calibration = _UNIFIED_CONSULTATION_ORCHESTRATOR.real_case_calibration_catalog(
route_packet=result.get("routing") if isinstance(result.get("routing"), dict) else route_packet,
+2
View File
@@ -183,6 +183,7 @@ def execute_consultation_workflow(
executed_steps.append('run_thematic_report')
vedastro_official = handler._high_rigor_vedastro_official_summary(chart)
vedastro_archive_manifest = handler._compute_vedastro_gateway_archives()
runtime_truth = vedastro_official.get('runtime_truth') if isinstance(vedastro_official.get('runtime_truth'), dict) else {}
interpretation_source_runtime_coverage = handler._interpretation_source_runtime_coverage(chart)
skipped_steps = [step for step in known_steps if step not in executed_steps]
@@ -190,6 +191,7 @@ def execute_consultation_workflow(
chart=chart,
route_packet=route_packet,
vedastro_official=vedastro_official,
vedastro_archive_manifest=vedastro_archive_manifest,
)
real_case_calibration = _UNIFIED_CONSULTATION_ORCHESTRATOR.real_case_calibration_catalog(
route_packet=route_packet,
@@ -66,6 +66,7 @@ class UnifiedConsultationOrchestrator:
"KP_cusp",
"external_oracle_status",
"vedastro_official_raw_response",
"vedastro_official_raw_archive_manifest",
]
_THEME_ALIASES = {
"relationship": "marriage",
@@ -368,6 +369,7 @@ class UnifiedConsultationOrchestrator:
chart: dict[str, Any] | None,
route_packet: dict[str, Any],
vedastro_official: dict[str, Any] | None = None,
vedastro_archive_manifest: dict[str, Any] | None = None,
) -> dict[str, Any]:
chart_data = chart if isinstance(chart, dict) else {}
modules = chart_data.get("modules") if isinstance(chart_data.get("modules"), dict) else {}
@@ -383,6 +385,7 @@ class UnifiedConsultationOrchestrator:
ascendant_sign = ascendant.get("sign") if isinstance(ascendant, dict) else None
functional_layer = derive_functional_benefic_malefic(ascendant_sign)
official = vedastro_official if isinstance(vedastro_official, dict) else {}
archive_manifest = vedastro_archive_manifest if isinstance(vedastro_archive_manifest, dict) else {}
raw_response = (
official.get("raw_response")
or official.get("official_raw_response")
@@ -417,6 +420,10 @@ class UnifiedConsultationOrchestrator:
"source_path": "vedastro_official.runtime_truth",
},
"vedastro_official_raw_response": self._section(raw_response, "vedastro_official.raw_response"),
"vedastro_official_raw_archive_manifest": self._section(
archive_manifest if archive_manifest.get("archive_count") else None,
"vedastro_gateway.archives",
),
}
missing = [name for name, section in sections.items() if section.get("status") == "missing"]
return {
+6
View File
@@ -2161,6 +2161,11 @@ def test_high_rigor_workflow_reuses_existing_rectification_backtest_and_vedastro
return _load_local_module(name)
monkeypatch.setattr(jyotish_api_server, '_load_local_module', fake_loader)
monkeypatch.setattr(handler, '_compute_vedastro_gateway_archives', lambda: {
'scope': 'vedastro_official_raw_response_archive_manifest',
'archive_count': 1,
'archives': [{'job_id': 'job_1955', 'official_raw_response_available': True}],
})
result = handler._compute_high_rigor_workflow({
'question': '请高严谨分析我的事业、婚恋和财富',
@@ -2199,6 +2204,7 @@ def test_high_rigor_workflow_reuses_existing_rectification_backtest_and_vedastro
assert result['unified_orchestrator']['name'] == 'UnifiedConsultationOrchestrator'
assert result['unified_orchestrator']['surface'] == 'api_web'
assert result['unified_orchestrator']['route']['question_type'] == 'career'
assert result['machine_evidence_packet']['sections']['vedastro_official_raw_archive_manifest']['status'] == 'used'
def test_consultation_workflow_uses_unified_orchestrator_contract(monkeypatch) -> None:
+1
View File
@@ -177,6 +177,7 @@ def test_mcp_strict_workflow_returns_runtime_evidence_log(monkeypatch) -> None:
assert result["runtime_evidence_log"]["route"]["question_type"] == "career"
assert result["runtime_evidence_log"]["vedastro_cloud_state"] == "official_verified"
assert result["machine_evidence_packet"]["status"] == "partial"
assert "vedastro_official_raw_archive_manifest" in result["machine_evidence_packet"]["sections"]
assert result["real_case_calibration"]["status"] == "partial_scored"
assert result["runtime_evidence_log"]["evidence_packet_contract"]["status"] == "partial"
assert result["runtime_evidence_log"]["real_case_calibration"]["status"] == "partial_scored"
@@ -311,3 +311,20 @@ def test_real_case_calibration_catalog_exposes_local_sources_without_claiming_ma
assert catalog["scored_candidates"][0]["event_trigger_match"]["checks"]["recorded_trigger_keywords"]
assert catalog["scored_candidates"][0]["outcome_validation"]["status"] == "local_outcome_recorded_trigger_not_replayed"
assert "D9" in catalog["scored_candidates"][0]["similarities"]["evidence_section_overlap"]
def test_machine_evidence_packet_carries_vedastro_raw_archive_manifest() -> None:
orchestrator = UnifiedConsultationOrchestrator()
packet = orchestrator.machine_evidence_packet(
chart={"chart": {"ascendant": {"sign": "Leo"}, "planets": {"Sun": {"sign": "Aquarius"}}}},
route_packet={"question_type": "career", "primary_theme": "career"},
vedastro_archive_manifest={
"scope": "vedastro_official_raw_response_archive_manifest",
"archive_count": 1,
"archives": [{"job_id": "job_1955", "official_raw_response_available": True}],
},
)
section = packet["sections"]["vedastro_official_raw_archive_manifest"]
assert section["status"] == "used"
assert section["source_path"] == "vedastro_gateway.archives"