Files
Jyotisha/AGENTS.md
T
Jesse_Chen 2415e751fe chore(repo): make the release gate reproducible and clean product URLs
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>
2026-09-03 16:55:26 +08:00

196 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Jyotisha Agent Constraints
本文件对所有协作代理生效(Claude Code、Codex、Cursor 以及派生工作流)。它把最容易被省略、或在多窗口工作时遗失的规则钉死。`CLAUDE.md` 只补充 Claude 会话的分工,不重复这里的规则;`frontend/AGENTS.md` 是 Next.js 版本提示。
全文分两部分:**Part A** 是所有代码与文档工作的约束;**Part B** 只在输出占星解读(解盘、推运、校正解释)时生效。
## 0. 先读什么
| 任务类型 | 开工前必读 |
| --- | --- |
| 任何任务 | 本文件 §1–§4`git status -sb` 的第一行(确认分支) |
| 前端改动 | `frontend/AGENTS.md``frontend/DESIGN.md``frontend/docs/VOICE.md`、§7 |
| Bug / 报错 / 回归 | §5,并检索 `docs/BUG_HISTORY.md` |
| 部署、线上故障、域名、登录、环境变量 | `deploy/README.md`(不要重新猜架构) |
| 引擎、外部 oracle、镜像边界、远端同步、发布 | §9 与 `docs/research/pre_work_error_ledger.md` |
| 领域术语(会话、轮次、故障、评价) | `CONTEXT.md`;命名与术语表一致,见 `docs/agents/domain.md` |
| 输出占星解读 | Part B |
---
# Part A · 代码与文档工作
## 1. 生产与环境真相
- Production domain: `https://jyotisha.chat`staging: `https://staging.jyotisha.chat`
- Primary source and the only CI/CD control plane: `https://git.copse.top/root/Jyotisha.git`Gitea)。GitHub `https://github.com/jesse-ux/Jyotisha.git` 是只读镜像:无 workflow、Actions 已关闭,不得用它验证交付状态,也没有 GitHub Issues 流程。
- Production host: Ubuntu VPS `118.194.235.34`,专用 `deploy` 用户,SSH 端口是部署变量;2 vCPU / 4 GB RAM,只跑 digest 固定镜像,不在主机构建。
- Runtime: `/opt/jyotisha-production`Compose project `jyotisha-production`Compose 文件 `deploy/docker-compose.server.yml`
- Secrets: `/opt/jyotisha-production/.env.production``.env.production.database``0600`);never print, copy into chat, or commit。
- Public edge: Caddy onlyNext.js `3000` 与 Python API `5200` 仅 Docker 内网。
- Persistence: 同主机私有 PostgreSQL 17 + Better Auth。从 Supabase 的迁移已切换完成;旧 VPS 不再是部署目标,Supabase 项目按 `docs/operations/production-server-migration-2026-08.md` 作为回滚资产保留到最终对账。
- API 容器有命名卷 `api_scratch`(chart 缓存与异步任务态);重计算端点受 `JYOTISH_HEAVY_COMPUTE_CONCURRENCY`(默认 2)限流,饱和返回 429。
部署安全规则:
1. 打包前 `git status --short --branch`;不得覆盖无关的脏文件。
2. 部署后验证 `/login`、未登录 `/api/account` = `401`、内部 `/api/health` = `200``swisseph_available = true``deployment.gitCommit` 必须等于预期 SHA。
3. 不得暴露端口 `5200`、模型 key、数据库口令、用户 JWT、SSH 私钥。
4. 生产部署只走 Gitea 手动流程(先 `release-quality-gate`,再 dispatch `deploy-production`),复用 staging 已验收的镜像 digest;不改 DNS、不导入生产数据。
## 2. 分支与交付
分支模型:`staging` 是测试环境,`main` 是生产控制分支。所有改动先经 `staging` 验收,再提升到 `main`;不存在直接改 `main` 的路径。
1. 动手前 `git fetch origin --prune`,以远端 **`origin/staging`** 为基线。本地 `staging` / `main` 经常落后远端上百个提交,不得作为基线。
2. 在独立 worktree 开发:路径 `.worktrees/<主题>-<日期>`,分支 `codex/<主题>-<日期>`(见 §3)。
3. 交付到 staging 用快进推送 `git push origin HEAD:staging`。这会触发 Gitea `backend-quality-gate`;它的 `paths:` 过滤与 `deploy/gated-paths.txt` 逐行一致。改动**全部**落在清单之外的纯文档推送(`docs/**`、根目录 `BLOCKED.md` / `CHANGELOG*.md` / `CONTEXT.md` / `AGENTS.md` / `CLAUDE.md` / `README.md` 等)不触发门禁、不发布镜像、不部署。鼓励把文档与同批代码合并一次推送,避免 staging head 与已部署 SHA 分离。
4. 门禁构建 digest 固定镜像并 dispatch `deploy-staging`;随后在 staging 完成与风险相称的验收。`GET /api/health``.deployment.gitCommit` 必须等于**最近一次含门禁路径改动的 staging 提交**;其后若只有纯文档提交,`deploy/is-docs-only-range.sh <该 SHA> <staging head>` 必须退出 0,否则视为未部署。
5. 提升到 `main` **必须快进,不得 merge**`deploy-production.yml` 强制 `main``staging` 指向同一 SHAmerge commit 会让生产部署失败。
6. 推送后必须核对远端 SHA;远端验证失败时不得声称已交付。
7. 不得自行提升 `main`、不改 `.gitea/workflows/**`、不动 DNS——这三件事只由产品负责人触发。
## 3. 工作树与多会话
同一台机器上经常有多个代理会话并行,主检出 `/workspace/Jyotisha` 可能被别的会话切到别的分支。
1. 任何 git 操作前先看 `git status -sb` 第一行确认分支;不要假设自己还在上次的分支上。
2. 代码工作只在自己的 worktree 里做:`git worktree add -b codex/<主题>-<日期> .worktrees/<主题>-<日期> origin/staging`
3. 文档/任务书推 staging 时,用专门跟踪 `staging` 的 worktree(例如 `.worktrees/staging-docs`):`git pull --ff-only origin staging` → commit → push;不要在主检出上直接 commit 到 staging。
4. 不得在有未提交修改的工作树上切分支、stash、reset、覆盖或顺带提交别人的变更;不得 reset / rebase 别的会话的分支。误落到别人分支上的提交用 cherry-pick 搬走并告知。
5. 两个同时改 `frontend/src/app/page.tsx` 或同一组件的轮次必须串行,任务书里写明先后。
## 4. 记录文件放哪
| 内容 | 位置 | 规则 |
| --- | --- | --- |
| 任务书、执行进度 | `docs/tasks/TASK-<主题>-<日期>.md``docs/tasks/PROGRESS-<主题>-<日期>.md` | 新文件只写这里,不再放仓库根目录;索引在 `docs/tasks/README.md` |
| 被环境/依赖挡住的事项 | `BLOCKED.md`(根目录) | 写清缺什么、替代证据是什么;解除后划掉而不是删除 |
| Bug 事实、根因、防复发 | `docs/BUG_HISTORY.md` | 见 §5;编号连续,开工时核对当前最大号 |
| 用户可感知的行为与 Skill 变化 | `CHANGELOG.md` | 日期 + 一句话标题 + 变更要点;Skill 版本是否 bump 写明 |
| 视觉、动效、等待态、间距 | `frontend/DESIGN.md` | 改 UI 的同一提交内更新;`CLAUDE_DESIGN.md` 是上游参照不改 |
| 文案口径 | `frontend/docs/VOICE.md` | 新文案先对照 |
| 真人验收清单 | `docs/testing/` | 自动化做不了的浏览器级验收写成可照做的条目 |
| 领域术语 | `CONTEXT.md` | 新术语先加到 glossary 再用 |
`docs/history/progress.md``docs/history/findings.md``docs/history/task_plan.md` 是早期实现日志,不是运行或部署说明,不再追加。
## 5. Bug History Workflow Hard Constraint
任何包含"Bug、报错、失败、异常、回归、无法保存、无法删除、状态码错误、线上故障"等现象的任务,开始诊断前必须用报错原文、接口路径、状态码、模块名和用户操作强制检索,并完整读完命中的记录。该文件体量已不允许通读全文,但检索不是可选步骤,命中记录的防复发措施是否仍然存在必须逐条确认:
- `docs/BUG_HISTORY.md`
这份文件是产品与代码 Bug 的长期历史入口;`docs/research/pre_work_error_ledger.md` 负责基础设施、外部引擎、碎片目录与预检风险,两者不得互相替代。
1. 修复前必须用报错原文、接口路径、状态码、模块名和用户操作搜索历史记录,优先检查相同模块的根因与防复发措施。
2. 若历史问题复发,必须关联原 `BUG-NNN`,说明旧测试、约束或发布门禁为何未拦住;不得把复发伪装成无关的新问题。
3. Bug 修复必须在同一变更中更新 `docs/BUG_HISTORY.md`:补充现有记录或新增连续编号,并记录状态、现象、触发条件、根因、修复、验证、防复发、关联记录和修复版本。
4. 若当轮只能诊断或被阻塞,也要把已确认事实写成 `investigating``blocked`,不得编造根因或提前标记 `resolved`
5. `resolved` 必须有与风险相称的证据:至少一个针对性回归测试;生产问题还必须有脱敏后的迁移、部署、健康检查或 smoke 证据。
6. Bug 历史严禁写入姓名、出生资料、邮箱、用户/案例 ID、Cookie、JWT、密码、密钥、完整请求体或模型原文。
## 6. 代码增长冻结
- `scripts/jyotish_api_server.py` must not grow. New endpoints and features go in dedicated modules under `scripts/` and are thinly registered from the main file. Do not add new handler bodies, workflows, or feature branches to this file. The cap is enforced by `tests/test_api_server_growth_contract.py`(冻结时行数 + 300 行 bugfix 余量)。
- `frontend/src/app/page.tsx` 已从 4,766 行拆到 2,000 行以下,**不得再增长**:新逻辑进 `frontend/src/hooks/``frontend/src/lib/` 或组件;参数式 hook 内部保持 0 个 React hook 的既定模式。
- 不得再手写第二个聊天输入框(一律 `ChatComposer`,自有草稿走 `value`)、第二套滚动跟随(一律 `useConversationScrollAnchor` + `JumpToLatestButton`)、第二套加载动画(揭幕后不得出现 spinner / 骨架 / "正在加载",流式生成中除外)。
## 7. 前端红线
1. `./node_modules/.bin/tsc --noEmit` 通过;`npm run lint` **0 error**react-hooks 编译器规则会拦 effect 内同步 setState、render 写 ref 等)。
2. `next build``/` 保持 `○ Static`;首屏 gzip 变化在 ±2% 内,超出要在进度记录里给出原因。
3. 测试总数不得低于开工时 `origin/staging` 的实测;改任何既有断言必须写"原值 / 新值 / 原因"三栏说明,不得静默弱化。
4. 合同测试的 fixture 必须来自真实引擎响应(golden),不得手造形状。
5. 改 UI 的提交同时更新 `frontend/DESIGN.md`;新文案对照 `frontend/docs/VOICE.md`
6. 不改数据库结构的轮次不得顺带动迁移;动表的轮次必须真跑 `npm run test:db`
7. 不得顺手升级依赖、不得顺手修不在任务书里的 warning;发现了写进 `BLOCKED.md` 或进度记录。
## 8. 隐私与安全
1. 真实用户出生资料、姓名、邮箱、会话内容、JWT、Cookie、密钥,不得进入 skill 文件、测试、CHANGELOG、Bug 历史、任务书、进度记录或任何提交。示例只用公开名人或明确虚构数据。
2. 不得读取、猜测或借用他人的凭据与账号做验收;没有受控账号就把该项写进 `BLOCKED.md`
3. 供应商地址必须经服务端 SSRF 防护;不得把任何 key 放进前端。
4. 不得放宽置信度或验证边界,除非有外部 benchmark 证据。
## 9. 开工预检(引擎 / 基础设施 / 发布类任务)
为避免多窗口、多镜像、碎片目录导致重复误判,涉及运行入口、镜像边界、外部 oracle、远端同步、适配器、发布或大规模资料治理的任务,开工前必须读取:
- `docs/research/pre_work_error_ledger.md`
若还涉及碎片目录或镜像仓,再读:
- `docs/research/whole_machine_fragment_sweep_2026_07_05.md`
- `docs/research/whole_machine_fragment_sweep_round25_2026_06_25.md`
并运行:
- `python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45`(包含 `scripts/diagnose_external_engine_adapters.py --json`
要求:不得把 `.workbuddy` 镜像当作运行主仓;不得在 `git ls-remote` / fetch / push 失败时声称云端已同步;新发现的重复错误、阻塞、碎片目录、远端验证失败追加到错误台账。
纯前端文案或组件改动不要求跑这条预检,但 §2、§3 照常。
## 10. 测试分层与环境缺口
| 层 | 命令 | 何时必跑 |
| --- | --- | --- |
| Python 快速门 | `.venv/bin/python scripts/run_quality_gate.py --profile quick` | 任何 Python 改动 |
| Python 定向 | `.venv/bin/python -m pytest tests/<file>.py` | 改了对应模块 |
| 前端 | `tsc --noEmit``npm run lint``npm test``npm run build` | 任何前端改动 |
| 数据库 | `npm run test:db --prefix frontend`(需 Docker | 动表 |
| 发布前 | `run_quality_gate.py --profile release` | 提升 `main` 前 |
已知环境缺口,遇到时如实写进 `BLOCKED.md` 而不是宣称通过:无 Docker(DB/部署套件阻塞,用与基线逐条一致的失败清单代替);无登录态与 Chrome(浏览器级验收留给 `docs/testing/` 清单);无模型凭据(真实模型输出留待部署后复核)。
---
# Part B · 解盘类任务硬约束(只在输出占星解读时生效)
以下规则不替代 `SKILL.md``references/strict-workflow-router.md`,而是把其中最容易被省略的高严谨要求单独钉死。纯计算、纯代码、纯项目维护任务不适用。
## B1. High-Rigor Override
当用户明确要求以下任一项时,必须进入高严谨模式:
- 不要凭经验泛谈
- 必须拉满三大开源参照引擎能力
- 必须提交底层原始数据
- 必须验证过去案例
- 必须避免偷工减料
进入该模式后,以下规则全部强制执行:
1. 必须尝试交叉参照 `PyJHora``VedAstro``jyotishganit`,并保持许可证边界。
2. 必须优先调用本仓原生实现,不得只用轻量包装脚本代替主链代码。
3. 涉及 timing / event / outcome,不得只看 `Vimshottari`,至少需要 `Vimshottari + Narayana Dasha` 双轨交叉。
4. 必须按问题域强制调取相关分盘:事业 `D10 + A10`;财富 `D2 / D11`;婚恋 `D9 + UL`
5. 必须交付原始数据依据:度数、Dasha 边界、Shadbala / Ashtakavarga、Yoga 名称、Ayanamsa / Node mode、外部证据路径。
## B2. Functional Benefic/Malefic Hard Constraint
**强制调取 Functional Benefic / Malefic 判定(功能性吉凶星判定)。** 这条约束与 Dasha / 分盘 / 原始数据交付同级,不得省略。
1. 每次进入高严谨模式,必须显式判定当前 Lagna 下的 `functional benefics``functional malefics`
2. 任何关于事业、财富、婚恋、健康、障碍、回报、应期的结论,都不得只依据自然吉凶星下判断,必须叠加功能性吉凶星层。
3. 若某颗星在自然属性与功能属性之间冲突,必须在输出中说明冲突来源,并降低置信度或标记 `blocked`
4. 若未调用功能性吉凶星判定,不得声称该次解读完成了高严谨模式。
5. Technique Audit Table 中必须出现 `Functional Benefic/Malefic` 一行,说明 `Used / not used / blocked`、关键功能吉星、关键功能凶星、对结论置信度的影响。
## B3. Existing MEVG Invocation Hard Constraint
**强制执行既有 MEVG 规则,不得把它当成可选增强项。** 本节不是新增一套验证系统,而是把 `SKILL.md``references/mandatory-verification-gate-protocol.md` 中已经存在的 MEVG 外部验证门控提升为协作代理硬约束。
1. 对用户提出的 **所有星盘运势类问题**、**所有有关印度占星推运的问题**,包括命盘解读、事业、财富、婚恋、健康、流年、流月、应期、事件预测、出生时间校正辅助和技法可靠性判断,必须执行 MEVG。
2. MEVG 必须包含:全球 / 全网外部资料采集、真实案例参考、来源分级、冲突仲裁、未验证声明降级。
3. 输出的 Technique Audit Table 必须出现 `MEVG / Global Web Evidence``Real Case Calibration` 两行。
4. 若无法完成外部资料采集、无法找到真实案例、网络/工具不可用、或来源之间出现重大冲突,必须写成 `blocked` 或降级置信度,不得静默跳过。
5. 只有 **纯计算 / 纯代码 / 纯项目维护** 可以豁免 MEVG(运行测试、检查 Git 状态、修复代码、输出未解释的原始度数或 Dasha 边界)。一旦开始解释"这代表什么运势",豁免立即失效。
## B4. Honesty Boundary
以下情况必须明确写成 `blocked` 或降级置信度:外部 oracle 尚未闭环;三大外部参照引擎中有一层无法合法或稳定调用;缺少分盘、Ayanamsa、Node mode 或出生精度;功能性吉凶星层未完成;双重大运或多系统结果发生实质冲突;MEVG / Global Web Evidence 或 Real Case Calibration 未完成。
禁止把内部一致性伪装成"已经全球顶级精度"。候选出生时间不得写成 confirmed;医疗、法律、投资、安全关键结论及确定性死亡/诊断/妊娠预测禁止。