2415e751fe
PyJHora absence is now partial, tests write research manifests to tmp, the registry allows experimental_variant, and product links point at the Gitea repo. Early logs move to docs/history. Co-authored-by: Cursor <cursoragent@cursor.com>
176 lines
12 KiB
Markdown
176 lines
12 KiB
Markdown
# Jyotisha — 中文印度占星对话产品
|
||
|
||
**Jyotisha**([jyotisha.chat](https://jyotisha.chat))是一个面向中文用户的印度占星(Jyotish / Vedic astrology)对话产品。用户用聊天的方式提问,Agent 依据本仓的 Python 计算引擎与 Skill 方法给出带证据边界的解读。产品有三个主面:
|
||
|
||
| 产品面 | 用户做什么 | 主要代码 |
|
||
| --- | --- | --- |
|
||
| 对话咨询 | 保存出生资料后直接提问事业、关系、时运等 | `frontend/src/app/page.tsx` + `frontend/src/mastra/` + Python `/api/consultation_workflow` |
|
||
| 生时校正 | 出生时间不确定时,通过访谈式问答收窄到可信区间与代表分钟 | `frontend/src/components/rectification-*`、`frontend/src/modules/`、`scripts/active_rectification_*.py` |
|
||
| 个人报告 | 按主题分章生成正式报告,附证据附录 | `frontend/src/components/personal-report/`、`skills/jyotish-personal-report/` |
|
||
|
||
另有管理后台(`/admin`:用户、订单、模型供应商、功能开关、对话质量记录)与点数计费。
|
||
|
||
[](LICENSE)
|
||
[](https://www.python.org/)
|
||
[](references/technique_registry.json)
|
||
[](references/technique_registry.json)
|
||
[](references/technique_registry.json)
|
||
[](references/technique_registry.json)
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
- [架构](#架构)
|
||
- [仓库地图](#仓库地图)
|
||
- [本地开发](#本地开发)
|
||
- [测试与门禁](#测试与门禁)
|
||
- [交付流程](#交付流程)
|
||
- [引擎与技法边界](#引擎与技法边界)
|
||
- [文档地图](#文档地图)
|
||
- [隐私与安全红线](#隐私与安全红线)
|
||
- [License](#license)
|
||
|
||
---
|
||
|
||
## 架构
|
||
|
||
```text
|
||
jyotisha.chat
|
||
-> Spaceship DNS
|
||
-> Caddy(生产 VPS 118.194.235.34,唯一公网入口 80/443)
|
||
-> Next.js + Mastra web 容器(3000,仅 Docker 内网)
|
||
-> Python Jyotish API 容器(5200,仅 Docker 内网)
|
||
-> Swiss Ephemeris 本地计算引擎
|
||
-> VedAstro Gateway(官方/自建/本地回退)
|
||
-> 私有 PostgreSQL 17 + Better Auth(账户、会话、点数、报告)
|
||
-> 外部 OpenAI-compatible 模型与邮件供应商
|
||
```
|
||
|
||
- Next.js 负责界面、输入校验、Agent 编排(Mastra)与流式回复;Python 服务是星盘、分盘、时序与证据计算的唯一事实来源;模型不得自行重算行星位置。
|
||
- 模型供应商与 API key 在管理端配置,AES-256-GCM 加密后存库;运行时不读供应商 key 环境变量。
|
||
- 生产与 staging 环境的所有事实(主机、端口、密钥位置、Compose 文件、部署与恢复命令)以 [`deploy/README.md`](deploy/README.md) 为准。staging 地址是 `https://staging.jyotisha.chat`。
|
||
|
||
## 仓库地图
|
||
|
||
| 路径 | 内容 | 生命周期 |
|
||
| --- | --- | --- |
|
||
| `frontend/` | Next.js 16 / React 19 产品前端、Mastra Agent、API 路由、Drizzle 迁移、前端测试 | 产品代码 |
|
||
| `scripts/` | Python 计算引擎、`jyotish_api_server.py` API 服务、校正引擎、质量门与工具脚本 | 产品代码 |
|
||
| `jyotish_vedic/` | Python 包入口(CLI、engine、MCP) | 产品代码 |
|
||
| `skills/` | Mastra 实际加载的 Skill 包(对话、校正、报告;含哈希锁定版本) | 产品代码 |
|
||
| `SKILL.md`、`references/` | 商业 Skill 入口与方法参照、技法注册表、oracle 样本、冻结的方法学 | 知识资产 |
|
||
| `contracts/` | 前后端共享的 JSON 合同 | 产品代码 |
|
||
| `deploy/` | Caddy、Compose、部署/迁移/恢复脚本、`gated-paths.txt` | 运维事实来源 |
|
||
| `.gitea/workflows/` | 唯一的 CI/CD 控制面(staging 门禁、生产手动发布) | 运维 |
|
||
| `tests/`、`frontend/tests/` | Python 与前端的回归/合同测试 | 产品代码 |
|
||
| `mcp_server.py` | 面向裁决器的 MCP 入口 | 产品代码 |
|
||
| `web/` | Python API 自带的调试页(`/`、`/evidence`、`/rectification`),不是产品 UI | 调试 |
|
||
| `docs/` | 任务书、Bug 历史、运维手册、测试清单、benchmark 看板、研究笔记 | 记录 |
|
||
| `benchmarks/`、`artifacts/` | 外部引擎对照与 e2e 采集产物 | 研究 |
|
||
| `scratch/local/` | 本地一次性脚本与输出,git 忽略 | 本地 |
|
||
|
||
新增文件前先判断它属于哪个生命周期:可复用的项目资产、活跃研究笔记、归档研究、本地脚本、本地输出。后两类不进仓库根目录。
|
||
|
||
## 本地开发
|
||
|
||
### 环境
|
||
|
||
- Python **3.11 或 3.12**,必须用项目自己的虚拟环境(`pyswisseph` 装在其中;系统 Python 3.9 不可用)。
|
||
- Node.js 20+。
|
||
- 本地数据库测试需要 Docker(起临时 PostgreSQL);没有 Docker 时相关测试会被跳过或阻塞,见 [测试与门禁](#测试与门禁)。
|
||
|
||
### 启动
|
||
|
||
```bash
|
||
# 首次:创建虚拟环境并安装引擎依赖
|
||
python3.12 -m venv .venv
|
||
.venv/bin/python -m pip install -r requirements.txt
|
||
|
||
# 1. Python API(星盘计算的事实来源)
|
||
.venv/bin/python scripts/jyotish_api_server.py --host 127.0.0.1 --port 5200
|
||
curl http://127.0.0.1:5200/api/health # swisseph_available 必须为 true
|
||
|
||
# 2. 网页
|
||
npm ci --prefix frontend
|
||
npm run dev --prefix frontend # http://localhost:3000
|
||
```
|
||
|
||
前端配置写在 `frontend/.env.local`(至少 `JYOTISH_API_BASE` 与 `MODEL_PROVIDER_CONFIG_ENCRYPTION_KEY`),细节见 [`frontend/README.md`](frontend/README.md)。仓库根目录的 `.env.local` 给 Python 侧用(VedAstro 模式等),模板是 `.env.cn.example` / `.env.official.example`;VedAstro 三种模式与中国大陆 Gateway 部署边界见 [`docs/engine/vedastro-gateway.md`](docs/engine/vedastro-gateway.md)。
|
||
|
||
## 测试与门禁
|
||
|
||
| 层 | 命令 | 说明 |
|
||
| --- | --- | --- |
|
||
| Python 快速门 | `.venv/bin/python scripts/run_quality_gate.py --profile quick` | 普通代码改动后必跑;`browser` / `release` / `accuracy` / `vedastro-live` 四个 profile 分别加前端、发布前、准确率、外部雷达检查 |
|
||
| Python 定向 | `.venv/bin/python -m pytest tests/<file>.py` | 合同测试会锁 README、AGENTS.md、行数上限等 |
|
||
| 前端类型与 lint | `cd frontend && ./node_modules/.bin/tsc --noEmit && npm run lint` | **lint 必须 0 error**(react-hooks 编译器规则已能分析首页) |
|
||
| 前端测试 | `npm test --prefix frontend` | 无 Docker 时 DB/部署套件会阻塞,比对失败清单与基线而不是宣称全绿 |
|
||
| 数据库测试 | `npm run test:db --prefix frontend` | 需要 Docker;动表的轮次必须真跑 |
|
||
| 生产构建 | `npm run build --prefix frontend` | `/` 必须保持 `○ Static` |
|
||
|
||
CI 只有 Gitea:推到 `staging` 触发 `backend-quality-gate`(构建 digest 固定镜像并部署 staging);纯文档推送(`deploy/gated-paths.txt` 之外的路径)不触发门禁、不部署。生产发布是手动流程,复用 staging 已验收的镜像。
|
||
|
||
浏览器级验收(登录、双标签页、刷新/后退、校正全流程)目前依赖真人按 [`docs/testing/`](docs/testing/) 的清单执行;自动化环境没有登录态与 Chrome。
|
||
|
||
## 交付流程
|
||
|
||
`staging` 是测试环境分支,`main` 是生产控制分支,`main` 只能从 `staging` 快进。协作代理的完整硬约束在 [`AGENTS.md`](AGENTS.md),Claude 会话的分工在 [`CLAUDE.md`](CLAUDE.md)。一轮工作的记录落点:
|
||
|
||
- 任务书与进度:`docs/tasks/`([索引](docs/tasks/README.md))
|
||
- 被挡住的事:`BLOCKED.md`
|
||
- Bug 事实与防复发:`docs/BUG_HISTORY.md`
|
||
- 行为与 Skill 变化:`CHANGELOG.md`
|
||
- 视觉与交互合同:`frontend/DESIGN.md`;文案口径:`frontend/docs/VOICE.md`
|
||
- 领域术语:`CONTEXT.md`
|
||
|
||
## 引擎与技法边界
|
||
|
||
The Python engine routes the technique registry (`references/technique_registry.json`, currently 91 entries: 78 covered, 8 complete, 4 guarded, 1 comparison-only) as a **backend evidence pool**, not as a flat list of user-facing prediction sources. The evidence-pool policy in `scripts/capability_evidence_pool.py` was written against 89 capability entries and its conclusion rules have not changed: the question-domain router selects a small primary chain (for example D10 + A10 for career, D9 + UL for relationships, D2 / D11 for wealth), uses supporting indicators only to raise or lower confidence, and every reading ends with a **Technique Audit Table** that says what was executed, what is `blocked`, and what is not applicable. Audit-only and alias entries cannot affect conclusions.
|
||
|
||
用户不知道问什么时,产品默认不反问,而是:
|
||
|
||
1. 调用统一入口 `/api/consultation_workflow`(MCP 对应 `strict_workflow`)。
|
||
2. 先生成 `evidence_packet`、`guided_topics` 与 Technique Audit Table。
|
||
3. 把 `guided_topics` 里的建议主题按优先级展示给用户,用户选题后再进入专题 `strict_workflow`。
|
||
|
||
从云端仓库加载后先跑 `python3 scripts/user_invocation_acceptance_check.py`,只有 `"status": "pass"` 且外部引擎状态被标为 `available` / `partial` / `missing_dependency` 时才做高严谨解盘。
|
||
|
||
诚实边界:所有 benchmark 看板固定输出 `can_claim_global_first: false` 与 `production_tuning_allowed: false`;`covered` 不等于外部 oracle 闭环。引擎定位、八阶段流水线、技法覆盖表与自评见 [`docs/engine/README.md`](docs/engine/README.md);准确率基线、外部 oracle 采集与看板命令见 [`docs/benchmark/README.md`](docs/benchmark/README.md)。
|
||
|
||
## 文档地图
|
||
|
||
| 想知道 | 看 |
|
||
| --- | --- |
|
||
| 协作代理必须遵守什么 | [`AGENTS.md`](AGENTS.md) |
|
||
| Claude 会话怎么分工、任务书怎么写 | [`CLAUDE.md`](CLAUDE.md) |
|
||
| 生产/staging 怎么部署、恢复、验证 | [`deploy/README.md`](deploy/README.md)、[`docs/operations/`](docs/operations/) |
|
||
| 前端怎么配、Skill 怎么触发 | [`frontend/README.md`](frontend/README.md) |
|
||
| 视觉与交互合同、文案口径 | [`frontend/DESIGN.md`](frontend/DESIGN.md)、[`frontend/docs/VOICE.md`](frontend/docs/VOICE.md) |
|
||
| 某个 Bug 以前出没出过 | [`docs/BUG_HISTORY.md`](docs/BUG_HISTORY.md) |
|
||
| 某轮任务做了什么、为什么 | [`docs/tasks/`](docs/tasks/README.md)、[`BLOCKED.md`](BLOCKED.md) |
|
||
| 真人验收清单 | [`docs/testing/`](docs/testing/) |
|
||
| 引擎定位与技法覆盖 | [`docs/engine/README.md`](docs/engine/README.md) |
|
||
| VedAstro / Codex 插件 / 用户级入口 | [`docs/engine/vedastro-gateway.md`](docs/engine/vedastro-gateway.md) |
|
||
| 准确率、oracle、benchmark | [`docs/benchmark/README.md`](docs/benchmark/README.md) |
|
||
| Skill 方法与真相覆盖层 | [`SKILL.md`](SKILL.md)、`skills/*/SKILL.md`、`references/` |
|
||
| 引擎/基础设施历史错误台账 | [`docs/research/pre_work_error_ledger.md`](docs/research/pre_work_error_ledger.md) |
|
||
| 架构决策记录 | [`docs/adr/`](docs/adr/) |
|
||
| 早期实现日志(不是运行说明) | [`docs/history/`](docs/history/README.md) |
|
||
|
||
## 隐私与安全红线
|
||
|
||
1. 真实用户出生资料、邮箱、姓名、会话内容、JWT、Cookie、密钥,**不得**进入 skill 文件、测试、CHANGELOG、Bug 历史、任务书或任何提交。
|
||
2. 测试与示例只用公开名人数据或明确虚构的数据。
|
||
3. 端口 `5200`、模型 key、数据库口令、SSH 私钥不得暴露;生产密钥只存在服务器 `0600` 文件中。
|
||
4. 不得放宽任何置信度或验证边界,除非有外部 benchmark 证据。
|
||
5. 医疗、法律、投资、安全关键结论与确定性死亡/诊断/妊娠预测禁止输出。
|
||
|
||
## License
|
||
|
||
MIT,见 [LICENSE](LICENSE)。
|
||
|
||
致谢:Swiss Ephemeris、PyJHora(`naturalstupid/PyJHora`)、VedAstro(`VedAstro/VedAstro`)、BPHS、PVN Rao / KN Rao 的教学传承。
|
||
|
||
> 本系统是研究与咨询辅助工具,不应在没有合格人类占星师参与的情况下用于改变人生的决定。
|