Add ordinary user delivery preflight
This commit is contained in:
@@ -30,6 +30,7 @@ COPY assets/ ./assets/
|
||||
|
||||
# ─── Verify installation ───
|
||||
RUN python -c "from jyotish_vedic import __version__; print(f'Jyotish v{__version__} ready')"
|
||||
RUN python3 scripts/deployment_preflight.py
|
||||
|
||||
# ─── Ports ───
|
||||
# 5200: REST API server
|
||||
|
||||
@@ -64,6 +64,17 @@ This is a **Vedic (Jyotish) astrology analysis system** designed for deep, audit
|
||||
4. 如果只安装 PWA:PWA 安装壳只包装网页服务,本地 API 服务仍需单独启动;无 API 时网页会保留基础浏览器 fallback,但 PDF/高级技法需要本地 API 服务。
|
||||
5. 开发者做完整自检时运行:`python3 scripts/run_quality_gate.py --frontend-click-timeout 240`。
|
||||
|
||||
### 普通用户交付形态
|
||||
|
||||
| 形态 | 入口 | 命令 | 能力边界 |
|
||||
|------|------|------|----------|
|
||||
| Local dev | `http://127.0.0.1:5173` | `cd jyotish-app && npm run dev -- --host 127.0.0.1 --port 5173` + `python3 scripts/jyotish_api_server.py --host 127.0.0.1 --port 5200` | 完整网页/app 用户端,适合本机普通用户试用。 |
|
||||
| Docker Compose | `http://localhost:5300` | `docker compose up -d` | 同时启动 Web shell 与本地 API,适合低门槛本机部署。 |
|
||||
| Static demo / PWA | 静态站点 URL | `cd jyotish-app && npm run build` | 公开演示环境只能完整展示静态壳;完整高级技法需要本地 API 服务。 |
|
||||
| Desktop shell | PWA / Pake / Tauri | `python3 scripts/desktop_packaging_preflight.py` | PWA/Pake 当前可用;Tauri sidecar 需等 API 生命周期、签名和权限策略固定。 |
|
||||
|
||||
发布前检查交付矩阵:`python3 scripts/deployment_preflight.py`。如果该命令失败,不要把当前构建交给普通用户。
|
||||
|
||||
### 质量门分层
|
||||
|
||||
- quick:快速开发守门,适合普通代码/文案修改后先跑:`python3 scripts/run_quality_gate.py --profile quick`
|
||||
|
||||
@@ -308,3 +308,6 @@
|
||||
- 云端 CI 收口完成:推送 `925e73e` 后,GitHub PR #6 最新 head 的 `validate`、`test`、`release-quality-gate` 三条检查均为 success;release-only browser/release 守门已在云端可运行。
|
||||
- 完成准确率透明度页面:Trust Center 新增 Validation Transparency,直接展示 `references/validation_logic_report.json` 当前 Yoga 对照口径:60 charts、82 comparable rules、Precision 96.48%、Recall 93.99%、F1 95.22%、unmapped_pyjhora 718,并明确这些是 Yoga 规则对照指标,不是个人事件预测准确率。
|
||||
- TDD/验证完成:先让 `test_trust_center_exposes_validation_transparency` 红灯确认缺口,再实现转绿;修复移动端 selector 回归后,`python3 -B -m pytest tests/test_frontend_productization.py::test_first_use_onboarding_is_actionable tests/test_frontend_productization.py::test_mobile_layout_keeps_dense_sections_single_column tests/test_frontend_productization.py::test_trust_center_exposes_validation_transparency -q` 通过;`npm run build --prefix jyotish-app` 通过;`python3 scripts/run_quality_gate.py --profile quick --skip-yoga-logic` 通过,覆盖 201 个核心 pytest、npm build 与 runtime smoke。
|
||||
- 完成普通用户交付形态矩阵:新增 `scripts/deployment_preflight.py`,输出 local-dev、docker-compose、static-demo-pwa、desktop-shell 四条 delivery_matrix,明确公开演示环境只能完整展示静态壳、完整高级技法需要本地 API 服务;README 增加“普通用户交付形态”表格;Dockerfile build 阶段运行 deployment preflight。
|
||||
- 交付矩阵纳入质量门:`scripts/run_quality_gate.py` 编译并执行 `scripts/deployment_preflight.py`,release hygiene 追踪该新文件,避免部署/公开演示路径漂移。
|
||||
- TDD/验证完成:`test_user_delivery_matrix_is_documented_and_checkable` 先红灯确认缺 `deployment_preflight.py`,实现后转绿;`python3 scripts/deployment_preflight.py` 输出 `valid: true`;`python3 scripts/run_quality_gate.py --profile quick --skip-yoga-logic` 通过,覆盖 202 个核心 pytest、npm build 与 runtime smoke。
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check ordinary-user delivery paths before publishing a Jyotish build."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
APP = ROOT / "jyotish-app"
|
||||
|
||||
|
||||
def read(path: Path) -> str:
|
||||
return path.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def require(condition: bool, label: str, failures: list[str]) -> None:
|
||||
if not condition:
|
||||
failures.append(label)
|
||||
|
||||
|
||||
def delivery_matrix() -> list[dict]:
|
||||
return [
|
||||
{
|
||||
"id": "local-dev",
|
||||
"label": "Local dev",
|
||||
"user_url": "http://127.0.0.1:5173",
|
||||
"commands": [
|
||||
"cd jyotish-app && npm run dev -- --host 127.0.0.1 --port 5173",
|
||||
"python3 scripts/jyotish_api_server.py --host 127.0.0.1 --port 5200",
|
||||
],
|
||||
"api_required": True,
|
||||
"scope": "Full web/app user experience with local API.",
|
||||
},
|
||||
{
|
||||
"id": "docker-compose",
|
||||
"label": "Docker Compose",
|
||||
"user_url": "http://localhost:5300",
|
||||
"commands": ["docker compose up -d"],
|
||||
"api_required": True,
|
||||
"scope": "Bundled API + web shell for local ordinary-user trials.",
|
||||
},
|
||||
{
|
||||
"id": "static-demo-pwa",
|
||||
"label": "Static demo / PWA",
|
||||
"user_url": "https://<static-host>/",
|
||||
"commands": ["cd jyotish-app && npm run build"],
|
||||
"api_required": False,
|
||||
"scope": "public demo shell; full advanced techniques require a local API service.",
|
||||
},
|
||||
{
|
||||
"id": "desktop-shell",
|
||||
"label": "Desktop shell",
|
||||
"user_url": "pwa://installed-app or pake://local-url",
|
||||
"commands": [
|
||||
"cd jyotish-app && npm run build && npm run preview -- --host 127.0.0.1 --port 4173",
|
||||
"python3 scripts/desktop_packaging_preflight.py",
|
||||
],
|
||||
"api_required": True,
|
||||
"scope": "PWA/Pake now; Tauri sidecar only after API lifecycle and signing are fixed.",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def main() -> int:
|
||||
failures: list[str] = []
|
||||
readme = read(ROOT / "README.md")
|
||||
dockerfile = read(ROOT / "Dockerfile")
|
||||
compose = read(ROOT / "docker-compose.yml")
|
||||
package = json.loads(read(APP / "package.json"))
|
||||
manifest = json.loads(read(APP / "public" / "manifest.webmanifest"))
|
||||
sw = read(APP / "public" / "sw.js")
|
||||
|
||||
require("普通用户交付形态" in readme, "README missing ordinary-user delivery matrix", failures)
|
||||
require("python3 scripts/deployment_preflight.py" in readme, "README missing deployment preflight command", failures)
|
||||
require("http://localhost:5300" in compose, "docker-compose missing ordinary web URL note", failures)
|
||||
require("python3 scripts/deployment_preflight.py" in dockerfile, "Dockerfile must run deployment preflight", failures)
|
||||
require("build" in package.get("scripts", {}), "jyotish-app missing build script", failures)
|
||||
require("preview" in package.get("scripts", {}), "jyotish-app missing preview script", failures)
|
||||
require(manifest.get("display") == "standalone", "PWA manifest must remain standalone", failures)
|
||||
require("url.pathname.startsWith('/api/')" in sw, "service worker must bypass API requests", failures)
|
||||
|
||||
result = {
|
||||
"valid": not failures,
|
||||
"failures": failures,
|
||||
"delivery_matrix": delivery_matrix(),
|
||||
"ordinary_user_note": "公开演示环境只能完整展示静态壳;完整高级技法需要本地 API 服务。",
|
||||
}
|
||||
print(json.dumps(result, ensure_ascii=False, indent=2))
|
||||
return 0 if not failures else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -23,6 +23,7 @@ COMPILE_DIRS = [
|
||||
EXTRA_COMPILE_TARGETS = [
|
||||
ROOT / "mcp_server.py",
|
||||
ROOT / "scripts" / "audit_fragments.py",
|
||||
ROOT / "scripts" / "deployment_preflight.py",
|
||||
ROOT / "tests" / "run_golden_cases.py",
|
||||
ROOT / "tests" / "run_frontend_runtime_smoke.py",
|
||||
]
|
||||
@@ -55,6 +56,7 @@ RELEASE_CRITICAL_UNTRACKED_PATHS = [
|
||||
"progress.md",
|
||||
"scripts/audit_fragments.py",
|
||||
"scripts/deep_varga_avastha.py",
|
||||
"scripts/deployment_preflight.py",
|
||||
"scripts/desktop_packaging_preflight.py",
|
||||
"scripts/ephemeris_adapter_contract.py",
|
||||
"scripts/ephemeris_backend_probe.py",
|
||||
@@ -278,6 +280,7 @@ def main() -> int:
|
||||
validate_json_files()
|
||||
run([PYTHON, "scripts/audit_capabilities.py", "--mode", "validate"])
|
||||
run([PYTHON, "scripts/audit_fragments.py", "--strict"])
|
||||
run([PYTHON, "scripts/deployment_preflight.py"])
|
||||
if profile["check_release_hygiene"]:
|
||||
release_hygiene_check()
|
||||
run([PYTHON, "scripts/validate_bphs_invariants.py"])
|
||||
|
||||
+2
-1
@@ -101,4 +101,5 @@
|
||||
- [x] CI 失败 artifact 诊断:pytest 改为 `-vv --maxfail=1 --junitxml`,quick/release quality gate 输出 tee 到 artifact,避免云端只暴露 exit code。
|
||||
- [x] 云端 CI 收口:PR #6 head `925e73e` 的 `validate`、`test`、`release-quality-gate` 三条 GitHub Actions 检查均已通过。
|
||||
- [x] 准确率透明度页面:Trust Center 新增 Validation Transparency 面板,展示 Yoga logic benchmark 的 60 charts、82 comparable rules、Precision/Recall/F1、unmapped_pyjhora 与“不是个人事件预测准确率”的边界说明。
|
||||
- [ ] 下一步:进入成品化最后一批缺口,优先补普通用户交付形态(部署/桌面打包/公开演示环境)。
|
||||
- [x] 普通用户交付形态:新增 deployment preflight 与 README 交付矩阵,明确 Local dev、Docker Compose、Static demo/PWA、Desktop shell 的入口、命令和 API 边界,并纳入 quick/release 守门。
|
||||
- [ ] 下一步:继续公开演示环境 polish,优先增加静态 demo 的离线/无 API 文案和部署目标示例。
|
||||
|
||||
@@ -1684,6 +1684,47 @@ def test_desktop_packaging_spike_is_documented_and_checkable() -> None:
|
||||
assert "python3 scripts/jyotish_api_server.py --host 127.0.0.1 --port 5200" in quality_gate
|
||||
|
||||
|
||||
def test_user_delivery_matrix_is_documented_and_checkable() -> None:
|
||||
preflight_path = ROOT / "scripts" / "deployment_preflight.py"
|
||||
assert preflight_path.exists()
|
||||
preflight = preflight_path.read_text(encoding="utf-8")
|
||||
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
dockerfile = (ROOT / "Dockerfile").read_text(encoding="utf-8")
|
||||
compose = (ROOT / "docker-compose.yml").read_text(encoding="utf-8")
|
||||
|
||||
for token in [
|
||||
"delivery_matrix",
|
||||
"local-dev",
|
||||
"docker-compose",
|
||||
"static-demo-pwa",
|
||||
"desktop-shell",
|
||||
"public demo shell",
|
||||
"api_required",
|
||||
"python3 scripts/jyotish_api_server.py --host 127.0.0.1 --port 5200",
|
||||
"npm run preview -- --host 127.0.0.1 --port 4173",
|
||||
"http://localhost:5300",
|
||||
]:
|
||||
assert token in preflight
|
||||
|
||||
for token in [
|
||||
"普通用户交付形态",
|
||||
"Local dev",
|
||||
"Docker Compose",
|
||||
"Static demo / PWA",
|
||||
"Desktop shell",
|
||||
"python3 scripts/deployment_preflight.py",
|
||||
"公开演示环境只能完整展示静态壳",
|
||||
"完整高级技法需要本地 API 服务",
|
||||
]:
|
||||
assert token in readme
|
||||
|
||||
assert "python3 scripts/deployment_preflight.py" in dockerfile
|
||||
assert "http://localhost:5300" in compose
|
||||
quality_gate = (ROOT / "scripts" / "run_quality_gate.py").read_text(encoding="utf-8")
|
||||
assert '"scripts/deployment_preflight.py"' in quality_gate
|
||||
assert '[PYTHON, "scripts/deployment_preflight.py"]' in quality_gate
|
||||
|
||||
|
||||
def test_user_startup_labels_are_consistent_across_recovery_surfaces() -> None:
|
||||
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
||||
quality_gate = (ROOT / "scripts" / "run_quality_gate.py").read_text(encoding="utf-8")
|
||||
|
||||
Reference in New Issue
Block a user