From 21565dc42f5ac33f114f65daf004c237cd16e37a Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Wed, 8 Jul 2026 22:13:05 +0800 Subject: [PATCH] feat: expose VedAstro official readiness in gateway --- docs/research/pre_work_error_ledger.md | 1 + scripts/vedastro_gateway.py | 21 +++++++++++++++++++++ tests/test_vedastro_gateway.py | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/docs/research/pre_work_error_ledger.md b/docs/research/pre_work_error_ledger.md index d278d16a..ab74d941 100644 --- a/docs/research/pre_work_error_ledger.md +++ b/docs/research/pre_work_error_ledger.md @@ -54,6 +54,7 @@ For large architecture or release work, also read: | 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. | | ERR-022 | Technique Audit Table can show VedAstro cloud state but omit whether archived official raw evidence is actually auditable. | mitigated 2026-07-08 | Keep `VedAstro Raw Archive Manifest` as a first-class Technique Audit Table row immediately after `VedAstro Cloud State`. | | ERR-023 | `professional_reading` can require a Technique Audit Table while omitting the user-visible VedAstro raw archive row. | mitigated 2026-07-08 | Keep `VedAstro Raw Archive Manifest` in `professional_reading.technique_audit_table_required_rows`. | +| ERR-024 | VedAstro gateway status can choose `local_fallback` before `.env` is loaded, even when official endpoint/network settings are present. | mitigated 2026-07-08 | `gateway_status()` must load official readiness before resolving active backend; `run_gateway_packet()` must expose `official_closure_state` separately from legacy `status`. | ## Fragment Sweep Command Set diff --git a/scripts/vedastro_gateway.py b/scripts/vedastro_gateway.py index 8d53e51f..d3ae525a 100644 --- a/scripts/vedastro_gateway.py +++ b/scripts/vedastro_gateway.py @@ -224,6 +224,9 @@ def run_gateway_job(job_id: str) -> dict[str, Any] | None: def gateway_status() -> dict[str, Any]: + from scripts.diagnose_vedastro_mode import build_report as build_vedastro_mode_report + + readiness = build_vedastro_mode_report() config = build_gateway_config() return { "scope": "vedastro_gateway", @@ -235,6 +238,13 @@ def gateway_status() -> dict[str, Any]: "cache_ttl_seconds": config["cache_ttl_seconds"], "queue_enabled": config["queue_enabled"], "fail_open_local": config["fail_open_local"], + "official_readiness": { + "official_ready": bool(readiness.get("official_ready")), + "mode": readiness.get("mode"), + "readiness_blockers": list(readiness.get("readiness_blockers") or []), + "free_tier_possible_with_cache_queue": bool(readiness.get("free_tier_possible_with_cache_queue")), + "official_closure_plan": readiness.get("official_closure_plan") or {}, + }, "direct_browser_access_allowed": False, "frontend_secret_safe": True, "boundary": BOUNDARY_TEXT, @@ -284,6 +294,16 @@ def _status_from_report(gateway: dict[str, Any], report: dict[str, Any]) -> str: return "blocked" +def _official_closure_state_from_report(gateway: dict[str, Any], report: dict[str, Any]) -> str: + catalog = report.get("official_capability_catalog") if isinstance(report, dict) else {} + active_backend = gateway.get("active_backend") or "local_fallback" + if active_backend == "local_fallback": + return "local_fallback" + if (catalog or {}).get("available"): + return "official_verified" + return "official_blocked" + + def run_gateway_packet( case: dict[str, Any], question: str = "", @@ -300,6 +320,7 @@ def run_gateway_packet( "scope": "vedastro_gateway_run", "schema_version": 1, "status": _status_from_report(gateway, report), + "official_closure_state": _official_closure_state_from_report(gateway, report), "gateway_status": gateway, "input": report.get("input") or {}, "runtime_mode": report.get("runtime_mode") or {}, diff --git a/tests/test_vedastro_gateway.py b/tests/test_vedastro_gateway.py index 1c1a5fbb..1bd9552e 100644 --- a/tests/test_vedastro_gateway.py +++ b/tests/test_vedastro_gateway.py @@ -5,6 +5,7 @@ def test_gateway_status_defaults_to_local_first_cn_safe(monkeypatch): from scripts import vedastro_gateway monkeypatch.delenv("VEDASTRO_GATEWAY_MODE", raising=False) + monkeypatch.setenv("JYOTISH_SKIP_LOCAL_ENV", "1") monkeypatch.delenv("VEDASTRO_SELF_HOST_ENDPOINT", raising=False) monkeypatch.delenv("VEDASTRO_API_ENDPOINT", raising=False) monkeypatch.delenv("VEDASTRO_CACHE_TTL_SECONDS", raising=False) @@ -19,6 +20,8 @@ def test_gateway_status_defaults_to_local_first_cn_safe(monkeypatch): assert status["frontend_secret_safe"] is True assert status["backend_priority"] == ["self_host", "official", "cache", "queue", "local_fallback"] assert status["active_backend"] == "local_fallback" + assert status["official_readiness"]["official_ready"] is False + assert "missing_endpoint" in status["official_readiness"]["readiness_blockers"] assert status["boundary"] == "Users never call VedAstro directly; backend gateway owns cache, queue, and fallback." @@ -39,6 +42,22 @@ def test_gateway_status_reports_cn_gateway_self_host(monkeypatch): assert status["queue_enabled"] is True +def test_gateway_status_exposes_official_readiness_gate(monkeypatch): + from scripts import vedastro_gateway + + monkeypatch.setenv("VEDASTRO_API_ENDPOINT", "https://api.vedastro.org/api") + monkeypatch.setenv("JYOTISH_SKIP_LOCAL_ENV", "1") + monkeypatch.setenv("VEDASTRO_ENABLE_NETWORK", "1") + monkeypatch.setenv("VEDASTRO_TIMEOUT_SECONDS", "20") + monkeypatch.setenv("VEDASTRO_FREE_TIER_QUEUE", "1") + + status = vedastro_gateway.gateway_status() + + assert status["official_configured"] is True + assert status["official_readiness"]["official_ready"] is True + assert status["official_readiness"]["free_tier_possible_with_cache_queue"] is True + + def test_gateway_run_packet_uses_user_entrypoint_and_marks_not_all_641(monkeypatch): from scripts import vedastro_gateway @@ -67,6 +86,7 @@ def test_gateway_run_packet_uses_user_entrypoint_and_marks_not_all_641(monkeypat assert packet["scope"] == "vedastro_gateway_run" assert packet["status"] in {"ok", "partial", "queued", "blocked", "cached", "local_fallback"} + assert packet["official_closure_state"] in {"official_verified", "official_blocked", "local_fallback"} assert packet["gateway_status"]["mode"] == "cn_gateway" assert packet["official_capability_catalog"]["summary"]["catalog_method_count"] >= 0 assert packet["honesty_boundary"]["all_641_methods_executed"] is False