接受删除旧报告页,并跟上最新 staging
旧的结构化报告页已由另一单删除,标识留在现在用的阅读页。测试不再读取那个文件。更新日志和 Bug 历史两边都保留。 自测:tsc 退出码 0;lint 0 error、123 warning;修复单点名的 3 个测试 7 通过、0 失败、0 取消。 Co-Authored-By: Grok (agent loop)
This commit is contained in:
+18142
-2
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
# PROGRESS · API 磁盘缓存留存(2026-10-14)
|
||||
|
||||
- 分支:`codex/api-disk-cache-retention-20261013`
|
||||
- 任务书基线写的是 `77057a819`。本分支从当时的 `origin/staging` `66cd60081f37a57680274633fcb3fb942d01bb2f` 拉出。A/B 的父提交用的是这个 SHA,不是任务书里的旧基线。
|
||||
- 接口文件行数:10946(验收口径 ≤ 10970)。类方法数和伪造点没有增加。
|
||||
|
||||
## 做了什么
|
||||
|
||||
- T1:新增 `scripts/api_scratch_retention.py`。启动时清理全部已登记目录,并按 `JYOTISH_SCRATCH_PRUNE_INTERVAL_SECONDS`(默认 1800,0 表示不启后台线程)周期清理。排盘缓存新文件改为仅本人可读,先写临时文件再换上。`prune_expired_async_jobs` 只留同名薄包装。
|
||||
- T2:`VEDASTRO_WRITE_AUDIT_ARTIFACTS` 默认关。关掉时不写审计文件,`artifact_path` 为 `None`。打开时写紧凑 JSON,仅本人可读,先写临时文件再换上。成功快照仍用原 TTL;失败、不完整、被挡住的用短 TTL,默认 300 秒,并且不超过成功 TTL。旧缓存没有 `negative` 标记时仍按成功的长期限读。状态接口改报含回落的成功期限,并多报失败期限。`.env.cn.example` 只加了注释,两个 604800 没改。
|
||||
- 成功的判据:`available is True` 且 `status == "ok"`。`partial` 即使 `available` 为真也算失败缓存。
|
||||
- T3:年月日能整除才收成整数,不截断 1990.5。时分秒和经纬度、时区能解析成有限数字就收成浮点,不四舍五入。解析不了的保持原值。日期取前 10 位,空值仍是空值。缓存格式版本 5 → 6。快速排盘和完整排盘仍是两把键。
|
||||
- T4:前台快照、负缓存、网关任务、分盘段都进了登记表。只删符合原文件名的过期文件。网关排队中和进行中的不删。读写逻辑和键没改。
|
||||
- T5:脚本在 `scripts/research/api_disk_cache_ab.py`,逐字节比较在 `scripts/research/api_chart_cache_byte_diff.py`。记录在 `docs/testing/api-disk-cache-retention-ab-20261013.md`。
|
||||
- T6:没有改咨询卡片缓存。数字用任务书 §2.5,没有重测:未命中构建 1.9 秒;文件 5097751 字节;命中时解析中位 68.5 毫秒;整次命中 82.5 毫秒;两天大约每个活跃用户 10 MB。可选方向仍是两条:按领域切片只读需要的部分;清理改为每隔几分钟一次,而不是每次读取都扫全目录。没有做进程内已解析包缓存。
|
||||
- T7:BUG-1330、BUG-1331、BUG-1332。变更说明一句。任务索引改为待验收。没有改界面说明。
|
||||
|
||||
## 命令和结果
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 新留存、异步任务、增长合同 | `pytest tests/test_api_scratch_retention.py tests/test_api_async_job_contract.py tests/test_api_server_growth_contract.py -q` | 26 通过 |
|
||||
| 安全缓存 | `pytest tests/test_api_server_security.py -q -k cache` | 6 通过 |
|
||||
| 任务书列出的 VedAstro / 咨询套件 | 见任务书 §8 那一条 | 4 失败,见下。其余通过 |
|
||||
| 需要审计文件的执行器测试 | `pytest tests/test_vedastro_service_adapter_executor.py::test_vedastro_range_scan_records_hashes_and_artifact_path -q` | 1 通过 |
|
||||
| 逐字节比较与 A/B | `python scripts/research/api_disk_cache_ab.py` | 退出码 0。命中率 B/A = 1.333。七天后 B 剩 40 个文件,等于当天键数。审计文件 0。负缓存剩 1。一万个文件的清理 20.174 秒 |
|
||||
| 接口行数 | 按换行计数 | 10946 |
|
||||
|
||||
既有断言改动只有一处,在 `tests/test_vedastro_service_adapter_executor.py`:原值是子进程沿用进程环境;新值是显式打开审计落盘;原因是默认关闭后这条测试仍要检查文件存在。这是测试前置,不是放宽断言。
|
||||
|
||||
## 未达到的目标(目标不改)
|
||||
|
||||
- 混合写法再重复 3 次时,命中率只是 A 的 1.333 倍,不是 2.5 倍。重复本身已经让 A 命中三分之二。
|
||||
- 一万个过期文件的清理用了 20.174 秒,不是 2 秒内。清理不在请求线程。默认间隔和失败短期限没有因此改掉。
|
||||
|
||||
## 本机套件里原先就会红的三条
|
||||
|
||||
- `tests/test_vedastro_gateway.py` 要求原始响应文件权限是 0600。Windows 报出来的是可写,不是 0600。这条断言没改。新测试在 Linux 上仍检查 0600,Windows 上只检查文件写出来了。
|
||||
- `tests/test_vedastro_runtime_ops.py` 要求已安装的 VedAstro 是 1.23.25,本机是 1.23.30。与这次缓存改动无关。
|
||||
- `tests/test_three_engine_parity_runner.py` 的公开盘回放把 PyJHora 记成 raw_imported,不是 structured_captured,同时在下载星历。运行器没改。
|
||||
|
||||
## 环境缺口
|
||||
|
||||
- 生产和测试环境里成功缓存的实际秒数,这份仓库读不到。部署后看状态接口的两个期限数字即可。
|
||||
- 生产卷上已经堆了多少文件,这里不知道。
|
||||
- 主测量挡住了 VedAstro 导入。本机有 SDK,官方端口能连通。不挡 SDK 的探针仍关闭外网取数,一次完整排盘 4.167 秒,没有报错,没有拉真实快照。
|
||||
|
||||
## 未做
|
||||
|
||||
- 没有改部署文件、生产环境变量、数据库,也没有手工清生产卷。
|
||||
- 没有把咨询卡片缓存并进周期清理。
|
||||
@@ -42,3 +42,22 @@ T6:`scratchpad/beta-smoke-checklist-20261014.md` 不在这棵树上。冒烟
|
||||
- 英文对话说明没有画在界面上,因为对话外壳只有中文。句子留在 VOICE。
|
||||
- T2b 按让步顺序跳过。
|
||||
- 冒烟草稿不在树里,改的是已经落盘的清单,没有另起一份。
|
||||
|
||||
## 第 1 次打回(2026-10-14)
|
||||
|
||||
接受最新 `origin/staging` 的合并。旧报告页 `personal-report-document-view.tsx` 按修复单删除,标识留在现在用的 Markdown 阅读页。AI 标识测试不再读取那个已删文件。更新日志和 Bug 历史两边都留着。Bug 历史在 staging 上本来就有前后两份,合并后仍是两份,本单只多了 BUG-1347 这一条。任务索引里补上修复单,并写上进度文件。
|
||||
|
||||
### 断言三栏(本轮)
|
||||
|
||||
| 位置 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `frontend/tests/ai-generated-notice-20261014.test.ts` 报告阅读用例 | 渲染已删除的旧结构化报告页,并检查中文标识和 `id="report-disclaimer"` | 删掉对旧页面的读取和这两条断言;Markdown 中英文标题下的断言、输入框断言保留 | 第 1 次打回:旧页面已由另一单删除,现行报告页已有标识 |
|
||||
|
||||
### 本轮自测
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 类型 | `frontend\node_modules\.bin\tsc --noEmit -p frontend` | 退出码 0 |
|
||||
| 规范 | `npm run lint --prefix frontend` | 退出码 0,0 error,123 warning(原有警告,本轮没有新增 error) |
|
||||
| 定向测试 | 在 `frontend` 下 `tsx --test` 跑修复单点名的 3 个文件 | tests 7,pass 7,fail 0,cancelled 0,退出码 0 |
|
||||
| 全量前端测试 / 构建 / 数据库 | 未跑 | 修复单不要求。数据库上一轮已过,这轮没改迁移 |
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# PROGRESS · 发问准备并行(2026-10-14)
|
||||
|
||||
- 分支:`codex/consult-prep-parallel-20261013`
|
||||
- 基线:`origin/staging` `66cd60081f37a57680274633fcb3fb942d01bb2f`(任务书写的 `77057a819` 的后代;计划评论里的 `2994588ad` 更早,不因此停工)
|
||||
- 个人长报告写作开关仍是关闭,本轮没有改报告章节
|
||||
- 编号:本分支上的 `docs/BUG_HISTORY.md` 最大号是 BUG-1322。BUG-1323~1336 被其它未合并任务书占用。本单用 BUG-1337~1339
|
||||
|
||||
## 开关
|
||||
|
||||
三个都保持代码里的默认,没有单独提交去打开:
|
||||
|
||||
| 开关 | 默认 | 原因 |
|
||||
| --- | --- | --- |
|
||||
| `CONSULT_PREP_PARALLEL` | 关 | 没有本机 Postgres 中位数,不满足首帧快两成 |
|
||||
| `MODEL_VERSION_CACHE_TTL_MS` | 0 | 没有量到「准备模型」快一半 |
|
||||
| `CONSULT_DOMAIN_CONCURRENCY` | 1 | 没有带星盘网络库的镜像重测;起草试算预计达不到快两成五 |
|
||||
|
||||
因此没有写 `CHANGELOG.md`,也没有改 `frontend/DESIGN.md`。
|
||||
|
||||
## 做了什么
|
||||
|
||||
- T1:开流前的登录、注销检查、请求体、会话、模型收进 `loadConsultTurnHead`。并行时注销检查和后面三条同时开始,失败仍按旧的先后返回。423 仍在任何扣点之前。
|
||||
- T2:并行打开时,审核在开流前启动、在扣点前等待。拦住时不扣点,并且比资料错误优先。关掉时仍是开流前等待审核。
|
||||
- T3:按模型和版本缓存成功的解析,最长 15 秒;失败和空结果不缓存;管理端清目录缓存时一并清掉。地址检查函数本身没改。已发布版本的供应商代码、类型和地址不可变,但启用开关和密钥仍可变,所以不能超过目录缓存的 15 秒。
|
||||
- T4:问题保存成功后立刻读标题,和分类同时进行,用到标题时再等。分类仍在扣点和保存之后。
|
||||
- T5:领域并发开关。为 1 时仍是原来的逐个循环,含时间预算。为 2 时一起算,结果按计划顺序组装,不再逐个套时间预算,领域个数上限不变。
|
||||
- T6:准备阶段记一条 `consultation-prep-v1`,只有阶段名、毫秒和状态,没有问题原文。
|
||||
- T7:见 `docs/testing/consult-prep-parallel-ab-20261013.md`。假时钟并行 160、串行 210。这不是开启依据。
|
||||
- 测试注入:模型目录增加 `setModelCatalogIoForTests`,只给测试替换查库、解密和地址检查。生产路径仍调用原来的函数。
|
||||
|
||||
## 改过的既有断言
|
||||
|
||||
| 文件 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `content-moderation.test.ts` | 源码含 `await moderate(visibleQuestion, "input"` 且早于 `reserve_consultation_usage` | `await settleInputModeration()` 早于扣点;准备服务里 `beforeReserve` 早于 `input.reserve()`;拦住时扣点次数是 0 | 审核挪到流内、扣点前。关掉开关时开流前的等待还在 |
|
||||
| `model-catalog.test.ts` | `return await readVersion(modelId, configVersion)` | `const model = await readVersion(...)`,只有非空才写入短缓存 | 绑版本的解析可以缓存,失败和空结果不写 |
|
||||
| `model-catalog.test.ts` | 咨询路由里 `if (!sessionModel)` 后面是 503 | 准备函数里 `if (!sessionModel)` 返回 `modelUnavailable()`,状态 503 | 模型不可用仍是开流前的 503,文案随准备步骤搬走 |
|
||||
| `consult-first-frame-and-pacing-20260928.test.tsx` | 401、请求体、会话不存在、会话类型、模型已变这些字面量在路由的 `runTurn` 之前 | 字面量在 `turn-prep.ts`;路由在 `runTurn` 之前调用 `loadConsultTurnHead` 并返回失败 | 开流前的判断收进同一个函数,状态码仍在开流前 |
|
||||
| `rectification-session-composer-guard.test.ts` | 咨询路由里会话缺失返回 404,类型不对返回 `session_not_consultation` | 同样两句在 `turn-prep.ts` | 会话判断搬走,文案和状态码没变 |
|
||||
|
||||
`consultation-agentic-runtime.test.ts` 的领域循环帮助函数现在也接受异步的假计算,以便断言「后完成的领域仍排在计划后面」。原有断言没有改松。
|
||||
|
||||
## 并发为 2 时的时间预算
|
||||
|
||||
领域数仍先被原来的上限截断(现在是 2)。开关为 2 时,这两个领域一起开始,不再逐个问「剩下的时间还够不够下一个」。开关为 1 时,原来的逐个判断还在。
|
||||
|
||||
## 自测
|
||||
|
||||
test:db 未跑:本轮没有改查询语句,任务书也不要求。前端全量和 Python 快速门留给验收。`npm run lint` 0 error,原有 warning 没动。
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 类型 | `node frontend/node_modules/typescript/bin/tsc --noEmit -p frontend` | 0 错 |
|
||||
| 规范 | `npm run lint --prefix frontend` | 0 error,125 条原有 warning |
|
||||
| 准备与审核 | `tsx --test` 下列文件:`consult-turn-prep-20261013`、`consult-prep-gate-20261013`、`content-moderation`、`model-catalog`、`consult-first-frame-and-pacing-20260928`、`rectification-session-composer-guard` | 准备函数 3 通过;门禁文件 5 通过;其余在同一次 41 例里通过(当时缓存测试还在改,后来单文件 5 通过、失败 0、取消 0) |
|
||||
| 计费、注销、标题、寒暄、领域 | 同上命令:`application-billing-contract`、`account-deletion`、`session-title-persist-contract`、`consultation-smalltalk`、`consultation-agentic-runtime` | 136 通过,失败 0,取消 0 |
|
||||
| 假时钟 | `consult-prep-parallel-ab.mts` | 并行 160,串行 210,同时步数 2 对 1 |
|
||||
| 领域镜像 | `consult-domain-concurrency-ab.py` | 退出 0,写明没有跑镜像 |
|
||||
|
||||
## 第 1 次打回
|
||||
|
||||
合并最新 `origin/staging`。业务代码没改,三个开关默认值没改。
|
||||
|
||||
| 文件 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `chat-session-authority.test.ts` | 在 `route.ts` 里找 `if (!chatSession)` 后的 404 | 在 `turn-prep.ts` 里锁 `sessionMissing()` 的 404,和分开的 `notConsultation()` 409 | 判定搬走了。仍不许并成一个判断 |
|
||||
| `consultation-workflow-contract.test.ts` | `beforeReserve: ({ consultationMode }) => createConsultationPlan({`,以及 `reserve: () => reserveConsultationModel(` | `beforeReserve` 的 async 函数体里调用 `createConsultationPlan({`,并且早于 `reserve`;`reserve` 的 async 函数体里调用 `reserveConsultationModel(` | 改成了 async。没有放宽成「文件里出现过函数名」 |
|
||||
| `consult-prep-parallel-ab.mts` | `frontend/scripts/research/`,从 `frontend/tests` 导入 | `frontend/tests/consult-prep-parallel-ab.mts` | 镜像会复制 scripts、不复制 tests。另一个新增的领域脚本是 Python,不导入测试目录 |
|
||||
|
||||
这次自测:上述合同测试加出生时间模式、镜像导入检查,40 通过,失败 0,取消 0。假时钟脚本挪走后仍是并行 160、串行 210。`tsc --noEmit` 0 错。`npm run lint` 0 error,125 条原有 warning。全量 `npm test` 留给验收。`git diff a0e223e2` 到本修复会带上合并进来的测试环境前端文件;相对那次合并的 `origin/staging`,`frontend/src` 没有新增改动。
|
||||
@@ -0,0 +1,243 @@
|
||||
# PROGRESS · 前端死代码与无调用方接口清理
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 分支:`codex/frontend-dead-code-20261013`
|
||||
- 基线:本分支从当前 `origin/staging` `0a4ba236580df6e6cbb0faa28e48d1e66ff7dfff` 拉出(任务书写作基线 `77057a819` 的后代)
|
||||
- 结论:删掉三个没有调用方的接口(含一个不用登录就会做大约 20 秒计算的入口)和任务书点名的死代码。普通导出的逐字节锁没动。Skill 版本不 bump。
|
||||
|
||||
## 开工基线
|
||||
|
||||
- 前端测试文件:600(`frontend/tests/*.test.ts` 与 `*.test.tsx`)。做完 594,少 6 个整文件。
|
||||
- `docs/BUG_HISTORY.md` 最大已有号是 BUG-1345。BUG-1342 当时空着,按任务书使用,不另开新号。
|
||||
|
||||
## 可达性脚本(正斜杠)
|
||||
|
||||
Windows 上 `os.walk` 给出反斜杠,任务书里的入口正则匹配不到。脚本先把路径换成 `/` 再判断。
|
||||
|
||||
删之前,不可达 17 个文件、3028 行,与任务书表一致:
|
||||
|
||||
```
|
||||
src/components/birth-time-life-events.tsx 207
|
||||
src/components/birth-time-soft-notice.tsx 36
|
||||
src/components/claim-boundary-badge.tsx 13
|
||||
src/components/evidence-audit-panel.tsx 64
|
||||
src/components/personal-report/personal-report-document-view.tsx 630
|
||||
src/components/personal-report/raw-appendix-download.tsx 33
|
||||
src/lib/agent-evals.ts 796
|
||||
src/lib/birth-time-candidate-completion.ts 14
|
||||
src/lib/chart-library-view.ts 18
|
||||
src/lib/db/client.ts 18
|
||||
src/lib/personal-report-longform-download.ts 8
|
||||
src/lib/rectification-agentic/core/index.ts 23
|
||||
src/lib/rectification-agentic/date-range.ts 53
|
||||
src/lib/rectification-agentic/session.ts 351
|
||||
src/lib/rectification-agentic/v9/index.ts 11
|
||||
src/lib/think-step-gate.ts 17
|
||||
src/mastra/rectification-tools.ts 736
|
||||
```
|
||||
|
||||
删之后还剩 2 个:
|
||||
|
||||
```
|
||||
src/lib/personal-report-longform-download.ts 8
|
||||
src/lib/reader-appendix-language.ts 32
|
||||
```
|
||||
|
||||
偏离:任务书 T2 写「只剩 `personal-report-longform-download.ts`」。那是在原始附录路由还在时的口径。T3 删掉路由和 `personal-report-raw-appendix.ts` 之后,净化函数 `reader-appendix-language.ts` 没有生产入口了,但密度测试和 `reader-appendix-language-parity.test.ts` 仍直接调用它。任务书没把它列入删除,删掉会放宽净化合同,所以保留。`ordinaryReportDownloadMarkdown` 仍在。
|
||||
|
||||
## 删除的源文件(行数按 git 删除计)
|
||||
|
||||
| 路径 | 行 |
|
||||
| --- | ---: |
|
||||
| `frontend/src/mastra/rectification-tools.ts` | 736 |
|
||||
| `frontend/src/lib/agent-evals.ts` | 796 |
|
||||
| `frontend/src/components/personal-report/personal-report-document-view.tsx` | 630 |
|
||||
| `frontend/src/lib/rectification-agentic/session.ts` | 351 |
|
||||
| `frontend/src/components/birth-time-life-events.tsx` | 207 |
|
||||
| `frontend/src/components/evidence-audit-panel.tsx` | 64 |
|
||||
| `frontend/src/lib/rectification-agentic/date-range.ts` | 53 |
|
||||
| `frontend/src/app/api/birth-rectification/route.ts` | 49 |
|
||||
| `frontend/src/app/api/reports/[reportId]/raw-appendix/route.ts` | 48 |
|
||||
| `frontend/src/lib/birth-rectification-payload.ts` | 41 |
|
||||
| `frontend/src/components/birth-time-soft-notice.tsx` | 36 |
|
||||
| `frontend/src/components/personal-report/raw-appendix-download.tsx` | 33 |
|
||||
| `frontend/src/lib/rectification-agentic/core/index.ts` | 23 |
|
||||
| `frontend/src/app/api/birth-time-candidate-completion/route.ts` | 20 |
|
||||
| `frontend/src/lib/chart-library-view.ts` | 18 |
|
||||
| `frontend/src/lib/db/client.ts` | 18 |
|
||||
| `frontend/src/lib/think-step-gate.ts` | 17 |
|
||||
| `frontend/src/lib/birth-time-candidate-completion.ts` | 14 |
|
||||
| `frontend/src/components/claim-boundary-badge.tsx` | 13 |
|
||||
| `frontend/src/lib/personal-report-raw-appendix.ts` | 13 |
|
||||
| `frontend/src/lib/rectification-agentic/v9/index.ts` | 11 |
|
||||
|
||||
源文件合计 3191 行。`drizzle-orm` 与 `@mastra/*` 依赖没删。`globals.css` 另删 11 行死样式(见 T5)。没改 `page.tsx`,没改 `scripts/jyotish_api_server.py`,没改表。
|
||||
|
||||
## 删除测试清单
|
||||
|
||||
整文件删除的原因都是:只测已经删掉的死代码。否定合同留在还活着的测试里。
|
||||
|
||||
### `frontend/tests/rectification-agentic-tools.test.ts`(14)
|
||||
|
||||
- gate tool posts the birth profile to /api/rectification_gate
|
||||
- score tool normalizes year-precision events into the V5 date range contract
|
||||
- scan tool derives its center and uncertainty from the server-owned range
|
||||
- gate keeps period-only profiles on the server-owned range without inventing a minute
|
||||
- scan defers an unknown full-day range instead of using a fake noon birth time
|
||||
- score rejects an Agent-invented range
|
||||
- save tool rejects before a confirmation gate exists
|
||||
- save tool rejects a time that does not equal the confirmed minute
|
||||
- confirm then save with the matching minute applies the write
|
||||
- confirm serializes event dates to the legacy precision contract
|
||||
- confirm persists ranked candidates with relative support totaling 100
|
||||
- confirm distinguishes skipped external validation from a failed VedAstro run
|
||||
- confirm offers non-unique candidates only when the Agent explicitly ends evidence collection
|
||||
- accept candidate tool delegates the exact persisted candidate and preserves accepted status
|
||||
|
||||
### `frontend/tests/rectification-agentic-session.test.ts`(16)
|
||||
|
||||
- loadAgenticRectificationProfile derives birth fields, accuracy and baseline
|
||||
- loadAgenticRectificationProfile normalizes a persisted ISO birth date
|
||||
- loadAgenticRectificationProfile normalizes a PostgreSQL Date birth date
|
||||
- loadAgenticRectificationProfile rejects an invalid persisted birth date
|
||||
- loadAgenticRectificationProfile treats hospital source as minute accuracy
|
||||
- loadAgenticRectificationProfile accepts a period-only declaration without a fake minute
|
||||
- loadAgenticRectificationProfile uses a custom declared window instead of the leftover period
|
||||
- loadAgenticRectificationProfile accepts an unknown time as the full day
|
||||
- loadAgenticRectificationProfile preserves a cross-midnight uncertainty range
|
||||
- loadAgenticRectificationProfile rejects a missing birth date
|
||||
- applyConfirmedBirthTime calls the service-role RPC with the confirmed minute
|
||||
- applyConfirmedBirthTime rejects a malformed time before calling the RPC
|
||||
- applyConfirmedBirthTime surfaces an RPC error as a failure
|
||||
- candidate persistence binds the engine result to user, session and profile baseline
|
||||
- candidate acceptance calls the service-role RPC with exact ownership and result identity
|
||||
- latest candidate result maps persisted support and selection state for session recovery
|
||||
|
||||
### `frontend/tests/agent-evals.test.ts`(11)+ `frontend/tests/fixtures/agent-golden-dataset-v1.json`
|
||||
|
||||
- golden fixture is deidentified and exactly covers every PR-8 10.1 subscenario and tag
|
||||
- a conforming rectification run passes every applicable deterministic scorer
|
||||
- deterministic scorers expose contract, evidence, theme, timing, focus, economy, and budget failures
|
||||
- catalog-only citations fail until the run actually makes the evidence available
|
||||
- fact and timing claims cannot disable deterministic evidence requirements
|
||||
- minute candidate and accepted states pass while unconsented confirmation fails
|
||||
- consented exact-minute confirmation passes only in the explicit confirmation case
|
||||
- requested theme coverage is independent from prose and uses structured theme ids
|
||||
- naturalness, repetition, follow-up relevance, and model fact review remain explicit pending inputs
|
||||
- latency and cost statistics use deterministic nearest-rank percentiles and report budget breaches
|
||||
- privacy scanner rejects identity fields, raw user bodies, credentials, dates, times, and internal paths
|
||||
|
||||
### `frontend/tests/birth-time-candidate-completion.test.ts`(1)
|
||||
|
||||
- unconfirmed candidate results cannot directly become the active consultation time
|
||||
|
||||
### `frontend/tests/public-thinking.test.ts`(5)
|
||||
|
||||
- incident English salad never reaches the public think channel
|
||||
- pure Chinese thinking is unchanged
|
||||
- CJK sentences are accepted whole; English words are not stripped
|
||||
- English-only process narration is dropped even without a terminator
|
||||
- an unterminated fragment is dropped rather than rewritten
|
||||
|
||||
### `frontend/tests/personal-report-raw-appendix.test.ts`(4 + 11 条参数化)
|
||||
|
||||
- raw appendix retains status rows and raw columns without changing ordinary projection
|
||||
- raw appendix cleans old cache vocabulary but leaves English prose intact
|
||||
- raw appendix keeps established HTML URL secret and chart-fence safety boundaries
|
||||
- raw appendix UI is independent of ordinary export and accepts no birth payload
|
||||
- raw appendix route guards anonymous
|
||||
- raw appendix route guards cross-origin
|
||||
- raw appendix route guards foreign
|
||||
- raw appendix route guards invalid-id
|
||||
- raw appendix route guards generating
|
||||
- raw appendix route guards missing
|
||||
- raw appendix route guards pending
|
||||
- raw appendix route guards wrong-report
|
||||
- raw appendix route guards wrong-owner
|
||||
- raw appendix route guards wrong-request
|
||||
- raw appendix route guards ready
|
||||
|
||||
### `frontend/tests/personal-report-view.test.ts` 里删掉的 15 条(文件留下,不再渲染旧阅读页)
|
||||
|
||||
- renders the selected answer-first order: cover -> summary -> D1 -> themes -> appendix -> disclaimer
|
||||
- accepted and confirmed birth times render as distinct report metadata states
|
||||
- v2 renders scope, natal foundation, themes, current phase, actions, blocked disclosures and provenance
|
||||
- v2 currentPhase is omitted when null, without hiding the remaining v2 sections
|
||||
- v2 chart evidence refs link to the appendix and every real structured chart uses the SVG renderer
|
||||
- v2 model-authored text stays escaped and cannot inject HTML, CSS or SVG
|
||||
- 技法审计表不会出现在核心判断之前
|
||||
- evidence appendix is collapsed by default in default mode and expanded in research mode
|
||||
- expandedByDefault=true expands the appendix even in default mode
|
||||
- birth-time sensitivity alone keeps the appendix visible and shows minute changes
|
||||
- D1 SVG renders when real houses exist; D9/D10 are never fabricated
|
||||
- each house owns its occupant coordinates and dense houses stay clipped and bounded
|
||||
- evidenceRefs only produce in-page anchors for ids present in the appendix
|
||||
- no dangerous HTML: no script tags, no external resources, no dangerouslySetInnerHTML
|
||||
- long theme sections are not forced to avoid page breaks; only small elements are
|
||||
|
||||
留下的 8 条:契约解析、路由信封、失败摘要、畸形文档、导出按钮、阅读外壳、打印、目录。
|
||||
|
||||
### `frontend/tests/rectification-decide-next-action.test.ts` 删 1 条
|
||||
|
||||
- core barrel re-exports decideNextAction without duplicating session helpers
|
||||
|
||||
原因:barrel 文件已删。旁边的决定逻辑测试还在。
|
||||
|
||||
### `tests/test_repo_privacy_markers.py`
|
||||
|
||||
- 参数化用例 `test_exact_synthetic_line_permission_rejects_mutations` 少 1 条:原来指向 `frontend/tests/agent-evals.test.ts` 的合成路径许可。文件没了,许可项一起删。函数名还在,其余许可项还在。
|
||||
|
||||
## 改写断言(三栏写在源码注释里)
|
||||
|
||||
| 位置 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `database-local-business.test.ts` 两处读取 | 用已删的 session 读取器核对候选 | 删掉读取。权限与 RPC 断言留着 | 读取器已删,库合同不变 |
|
||||
| `personal-report-progress.test.ts` | 旧阅读页必须引用共享章节名 | 删这两条。共享表断言留着 | 旧阅读页已删 |
|
||||
| `personal-report-export.test.ts` | 旧阅读页源码不得内嵌 HTML | 删这条。页面不得出现旧视图名字的断言留着 | 文件已删 |
|
||||
| `rectification-step-answer.test.ts` | 读思考门源码,不得有组装函数 | 删这两行。连续 reasoning-delta 必须丢弃留着 | BUG-953,文件已删 |
|
||||
| `evidence-audit-panel.test.ts` | 内部面板文案和死样式必须存在 | 删正向断言。聊天不得挂内部面板、读者审计表样式留着 | 面板已删,否定合同不放宽 |
|
||||
| `claim-boundary-badge.test.ts` | 徽章文案和死样式必须存在 | 删正向断言。聊天行不得挂徽章留着 | 同上 |
|
||||
| `global-birth-profile-routes.test.ts` | 旧校正载荷构造器用同一组坐标 | 删这段。每日与合盘断言留着 | 构造器已删 |
|
||||
| `personal-report-density-retry.test.ts` | 原始附录出口不含内部词,并再打一次已删接口 | 直接核对快照:旧缓存没有计算快照;其余快照的适用性原文和正文与已保存的一致。净化函数的断言留着 | 出口已删,快照合同不放宽 |
|
||||
| `test_daily_and_rectification_entrypoints.py` | 钉住代理源码 | 路由文件不存在,且网页 API 目录下没有路由再转发到内网问卷路径。测试名保留,测试数不降 | BUG-1342 |
|
||||
| `test_repo_privacy_markers.py` 自检 | 替换已删除许可项里的那条合成路径 | 改为替换仍留在许可表里的另一条合成路径 | 改了许可原文仍必须被扫到,不放宽 |
|
||||
|
||||
## T5 死样式
|
||||
|
||||
删前在 `frontend/src` 与 `frontend/tests` 里,这些类只出现在即将删除的组件和即将改写的测试里。删后源码不再引用:`.claim-boundary-badge`、`.evidence-audit-panel`、`.evidence-audit-table`、`.evidence-audit-row`、`.raw-evidence-receipt`、`.birth-time-life-events`。`.personal-report-document`、`.technique-audit`、`.markdown-table` 没动。
|
||||
|
||||
## 自测
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 类型 | `frontend\node_modules\.bin\tsc --noEmit -p frontend` | 0 错 |
|
||||
| lint | `npm run lint --prefix frontend` | 0 error,123 warning(开工口径 125,少 2,就是随 `birth-time-candidate-completion.ts` 消失的那两条;其余未改) |
|
||||
| 改过的前端测试 | `node node_modules\tsx\dist\cli.mjs --test` 在 `frontend` 下跑点名的文件 | fail=0,cancelled=0。含密度 10 个模式与阅读页留下的 8 条 |
|
||||
| Python | `.venv\Scripts\python -m pytest tests/test_daily_and_rectification_entrypoints.py tests/test_repo_privacy_markers.py -q` | 4 + 62 收集,exit 0 |
|
||||
| 数据库 | `npm run test:db --prefix frontend` | 80 条:通过 67,失败 13,cancelled 0。失败名与 `windows-known-failures.txt` 逐条相同,没有多出来的。改过的本地业务库测试通过 |
|
||||
|
||||
没跑前端全量 `npm test`、Python 快速门、`next build`。
|
||||
|
||||
## test:db
|
||||
|
||||
`npm run test:db --prefix frontend` 退出码 1,因为 Windows 上那 13 条本来就会失败。失败名与 `tools/agent-loop/windows-known-failures.txt` 一致,没有新增:
|
||||
|
||||
- staging backups are encrypted, atomic, private, and retain the newest three
|
||||
- rejects destructive backup directory aliases and symlink components before mutation
|
||||
- rejects unsafe writable backup parents before creating the target
|
||||
- rejects a direct canonical sticky shared backup directory before chmod
|
||||
- creates every absent backup path component privately despite a permissive caller umask
|
||||
- same-second backups publish once without overwriting the completed archive
|
||||
- find enumeration failures preserve existing backups and do not report completion
|
||||
- refuses full disks and removes a failed-pipeline partial file
|
||||
- database env validator accepts punctuated literal required secrets
|
||||
- database env validator enforces an explicit staging owner uid without printing values
|
||||
- database env validator accepts a private valid file without printing values
|
||||
- personal report job migration is atomic, lease-bound, recoverable, and owner read-only
|
||||
- personal report sections enforce owner-read RLS and service-owned durable transitions
|
||||
|
||||
改过的 `database-local-business.test.ts`(local PostgreSQL applies the reviewed business schema and serves authenticated business calls)通过。权限和 RPC 断言还在。
|
||||
|
||||
## 第 1 次打回
|
||||
|
||||
合并最新 `origin/staging`。从 `knownUnstyled` 删掉 `personal-report-additional-charts`。其它白名单里没有被删组件留下的类名。业务代码没改。类名合同和两条否定合同 6 通过,失败 0,取消 0。`tsc` 0 错。`lint` 0 error,123 条原有 warning。
|
||||
@@ -0,0 +1,44 @@
|
||||
# PROGRESS · 长报告出稿提速(2026-10-14)
|
||||
|
||||
- 分支:`codex/report-reference-perf-20261013`
|
||||
- 实际基线:`origin/staging` `66cd60081f37a57680274633fcb3fb942d01bb2f`(任务书写的 `77057a819`、计划评论里的 `2994588ad` 都更早,按当前 staging 开工)
|
||||
- `scripts/jyotish_api_server.py`:10335 行,零改动
|
||||
- 历史最大号在本基线上是 BUG-1322。BUG-1323~1334 已被其它未合入任务书占用。本单用任务书指定的 BUG-1335、BUG-1336。
|
||||
|
||||
## 做了什么
|
||||
|
||||
1. 两个开关在调用时读环境变量。渲染快捷路径默认关,同盘缓存默认开。
|
||||
2. 中文和英文的大运密度补句:正则预编译,行内先看必出现的字面量,没有才不搜索;向前看的五行只在可能命中时才拼。术语替换:正文里没有这个词就原样返回,编译结果按词缓存。
|
||||
3. 溯源哈希在开关打开时,一次遍历同时删掉 `**.键` 并做键名规范化。覆盖范围和排除集没变。没有跳过中间那次绑定,因为那会改 `format=json` 的键顺序。
|
||||
4. 咨询卡缓存的单飞和两天清理多了一个子目录参数,咨询卡自己的键和目录不变。长报告只在完整数据版 + markdown、开关开、并且 `GITHUB_SHA` 是具体版本号时,才把整份响应放进 `scratch/local/report_reference_cache/`。查缓存发生在重计算之前。命中打一行不含资料的日志。
|
||||
|
||||
## 自测
|
||||
|
||||
| 检查 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 任务书列出的 pytest | `.venv\Scripts\python.exe -m pytest` 后接任务书第 8 节那一串文件 `-q` | 退出码 0。缓存默认改成开之后又跑了一遍,仍是退出码 0 |
|
||||
| 屏蔽 PyJHora 的 A/B | `python scripts/research/report_reference_perf_ab.py --mask-pyjhora` | 四张盘五字段 sha 相同;端到端下降 20%~23%,未达 35%;缓存命中中位约 0.06 秒 |
|
||||
| 同一份解盘的 json / reference | 同上脚本 `--side-only` | 退出码 0。时钟钉死且复用同一次解盘后,两版 sha 相同 |
|
||||
| 不屏蔽 | 未跑 | 本机没有 PyJHora,和屏蔽走同一条导入失败路径 |
|
||||
|
||||
数字见 `docs/testing/report-reference-perf-ab-20261013.md`。
|
||||
|
||||
## 改既有断言
|
||||
|
||||
无。原值 / 新值 / 原因:没有改旧断言。
|
||||
|
||||
## 未做
|
||||
|
||||
- 整篇替换逐条预检(让步顺序里最先砍的一项)。中文渲染只降了 20%~28%,不到 40%,没有为了过线改输出。
|
||||
- 跳过中间绑定。
|
||||
- 关掉没人读的质量门。任务书写明这要另开单,本单不动。
|
||||
- 旧路径退役。开关还在。
|
||||
|
||||
## 默认值
|
||||
|
||||
- `JYOTISH_REPORT_RENDER_FAST` 默认关。字节一致,内存还降了约 12%,但端到端没到 35%。
|
||||
- `JYOTISH_REPORT_REFERENCE_CACHE` 默认开。命中与未命中字节一致,命中中位约 0.06 秒。版本号缺失或是 `unknown` 时不缓存。
|
||||
|
||||
## 第 1 次打回
|
||||
|
||||
合并最新 `origin/staging` 后,把 `report_reference_cache` 登记进 `OFFLINE_SCRATCH_NAMES`。清理逻辑没改:这个目录仍由 `consult_full_data_cache.get_or_build` 在每次调用时删掉两天前的文件。没有改两个缓存模块的行为。
|
||||
@@ -332,7 +332,8 @@
|
||||
| `TASK-rectification-refresh-r3-r4-20260913.md` | `PROGRESS-rectification-refresh-r3-r4-20260913.md` | 刷新阶段 R3(MIN_BOUNDARY_DAYS 45→30)+ R4(pratyantar 与 D9/D10 上升 Narayana);首轮出题不变。即使放宽仍有 0 题例子,定向补事另线保留(BUG-664/665) | 已实现 `ab1ade59`,已部署;2026-09-13 验收通过(实现单由执行方自拟,无产品决策记录段;收益口径见研究文档) | `codex/rectification-refresh-r3-r4-20260913` |
|
||||
| `TASK-upstream-sync6-20261007.md` | [PROGRESS-upstream-sync6-20261007.md](PROGRESS-upstream-sync6-20261007.md) | **上游同步第六轮(`23be1807`)**:10-05 五个计算修正一行未合——D5/D6/D8/D11 映射(乔布斯盘四张分盘星座全不同)、Vimsopaka 权重、Yogini 顺序与出生余额、Panchadhikari 宫位参照、Narayana 并列、特殊上升、出生秒数、Neecha Bhanga 两条件、首段大运子运、岁差被覆盖;逐项对照原书核实;最先做 | 已验收(门禁补修 `2df6ee72`,已部署 staging) | [PROGRESS-upstream-sync6-20261007.md](PROGRESS-upstream-sync6-20261007.md) |
|
||||
| `TASK-upstream-sync7-20261014.md` | [PROGRESS-upstream-sync7-20261014.md](PROGRESS-upstream-sync7-20261014.md) | **上游同步第七轮(BUG-1318 起)**:婚恋评级断语改证据档位、DK「婚姻质量 X/100」改对;KP 宫头到宫头判宫;瑜伽宫主排序去重;api_server 大运年长 365.25;星历路径只核查。不动校正打分。Grok 执行(agent 循环) | 待验收 | `codex/upstream-sync7-20261014`(BUG-1318~1321 已改;BUG-1322 星历路径核查中,未改代码) |
|
||||
| `TASK-beta-main-path-20261014.md` | `PROGRESS-beta-main-path-20261014.md` | **内测主路径**:BUG-1063 他人报告 worker 读档案(逐列只读授权 + test:db);对话与报告「AI 生成,仅供参考」标识与免责;BUG-1080/283 状态;状态板按事实清账;冒烟清单 `docs/testing/beta-smoke-20261014.md`。与发布单并行 | 待验收 | `codex/beta-main-path-20261014` |
|
||||
| `TASK-beta-main-path-20261014.md` | `PROGRESS-beta-main-path-20261014.md` | **内测主路径**:BUG-1063 他人报告 worker 读档案(逐列只读授权 + test:db);对话与报告「AI 生成,仅供参考」标识与免责;BUG-1080/283 状态;状态板按事实清账;冒烟清单 `docs/testing/beta-smoke-20261014.md`。与发布单并行 | 第 1 次打回后已修,待验收 | `codex/beta-main-path-20261014` |
|
||||
| `TASK-beta-main-path-fix-20261014.md` | `PROGRESS-beta-main-path-20261014.md` | **#73 第 1 次打回**:`fca62fda` 内容通过;与 #63 删除的旧报告视图有代码冲突,接受删除即可 | 待验收 | `codex/beta-main-path-20261014` |
|
||||
| `TASK-release-path-production-20261014.md` | — | **发布通路 + 生产首发**:产品 10-14 授权改生产工作流(发布 SHA = 最近门禁成功提交 + 其后纯文档);63 个迁移清单与演练脚本、首发 runbook;生产拒绝测试验证码。Grok 不 dispatch 生产工作流 | 待执行 | — |
|
||||
| `TASK-beta-safety-net-20261014.md` | — | **内测安全网**:每日备份 + 恢复演练、探活告警、本地错误汇总、日志轮转、按 requestId 查日志。**等发布通路单合入、#58 合入后开工** | 待前置 | — |
|
||||
| `TASK-beta-capacity-20261014.md` | — | **内测容量**:按用户限流、重计算短排队与对话重试、兑换码当邀请码、staging 10/20 并发压测。**等 #58 合入后开工,压测等 #57 合入** | 待前置 | — |
|
||||
@@ -472,10 +473,13 @@
|
||||
| `TASK-node-runtime-resources-fix-20261014.md` | `PROGRESS-node-runtime-resources-20261013.md` | **#58 第 1 次打回**:`4c3485bc` 其余全过;压测脚本放在 `frontend/scripts/` 却从 `frontend/tests/` 导入,镜像构建会失败(BUG-1140 形状,任务书指定的路径有误)。挪到 `frontend/tests/` 下非 `.test` 文件名 | 待验收 | `codex/node-runtime-resources-20261013` |
|
||||
| `TASK-home-sidebar-rerender-20261013.md` | `PROGRESS-home-sidebar-rerender-20261013.md` | 流式回答时侧栏每帧整栏重渲染(BUG-1329,A/B) | 待验收 | `codex/home-sidebar-rerender-20261013` |
|
||||
| `TASK-home-sidebar-rerender-fix-20261014.md` | `PROGRESS-home-sidebar-rerender-20261013.md` | **#59 第 1 次打回**:`63509431` 其余全过;`chat-navigation-a11y-contract` 按源码文本断言 `onOpenBilling` 旧写法未跟改(§7.8) | 待验收 | `codex/home-sidebar-rerender-20261013` |
|
||||
| `TASK-api-disk-cache-retention-20261013.md` | — | API 磁盘缓存只进不出、VedAstro 审计文件留存出生资料、失败快照久缓存、缓存键规范化(BUG-1330~1332,A/B) | 待领取 | `codex/api-disk-cache-retention-20261013` |
|
||||
| `TASK-report-reference-perf-20261013.md` | — | 长报告出稿提速:术语替换命中预检、哈希单次遍历、同盘复用(BUG-1335~1336,A/B) | 待领取 | `codex/report-reference-perf-20261013` |
|
||||
| `TASK-consult-prep-parallel-20261013.md` | — | 普通对话发问前准备步骤并行、模型版本短缓存、多领域并发开关(BUG-1337~1339,A/B) | 待领取 | `codex/consult-prep-parallel-20261013` |
|
||||
| `TASK-frontend-dead-code-20261013.md` | — | 前端死代码 17 文件与无调用方接口删除,含未登录重计算接口(BUG-1342) | 待领取 | `codex/frontend-dead-code-20261013` |
|
||||
| `TASK-api-disk-cache-retention-20261013.md` | `PROGRESS-api-disk-cache-retention-20261013.md` | API 磁盘缓存只进不出、VedAstro 审计文件留存出生资料、失败快照久缓存、缓存键规范化(BUG-1330~1332,A/B) | 待验收 | `codex/api-disk-cache-retention-20261013` |
|
||||
| `TASK-report-reference-perf-20261013.md` | `PROGRESS-report-reference-perf-20261013.md` | 长报告出稿提速:术语替换命中预检、哈希单次遍历、同盘复用(BUG-1335~1336,A/B) | 待验收 | `codex/report-reference-perf-20261013` |
|
||||
| `TASK-report-reference-perf-fix-20261014.md` | `PROGRESS-report-reference-perf-20261013.md` | **#61 第 1 次打回**:`69c739fb` 本单全过;与清理规则合并后,长报告缓存目录补进自行清理名单 | 待验收 | `codex/report-reference-perf-20261013` |
|
||||
| `TASK-consult-prep-parallel-20261013.md` | `PROGRESS-consult-prep-parallel-20261013.md` | 普通对话发问前准备步骤并行、模型版本短缓存、多领域并发开关(BUG-1337~1339,A/B) | 待验收 | `codex/consult-prep-parallel-20261013` |
|
||||
| `TASK-consult-prep-parallel-fix-20261014.md` | `PROGRESS-consult-prep-parallel-20261013.md` | **#62 第 1 次打回**:两条源码文本检查改认新位置,对照脚本挪进测试目录 | 待验收 | `codex/consult-prep-parallel-20261013` |
|
||||
| `TASK-frontend-dead-code-20261013.md` | `PROGRESS-frontend-dead-code-20261013.md` | 前端死代码 17 文件与无调用方接口删除,含未登录重计算接口(BUG-1342) | 待验收 | `codex/frontend-dead-code-20261013` |
|
||||
| `TASK-frontend-dead-code-fix-20261014.md` | `PROGRESS-frontend-dead-code-20261013.md` | **#63 第 1 次打回**:类名白名单去掉已删组件留下的条目 | 待验收 | `codex/frontend-dead-code-20261013` |
|
||||
| `TASK-api-chart-subprocess-gate-20261013.md` | — | 合盘不带 skip 串行排盘、报告无效子进程、名额轻重混用(只模拟)(BUG-1333~1334,A/B) | 待领取(排队:api-disk-cache-retention + report-reference-perf) | `codex/api-chart-subprocess-gate-20261013` |
|
||||
| `TASK-answer-effort-ab-20261013.md` | — | 答题步推理强度开关 + A/B(需模型 key) | 待领取(排队:consult-prep-parallel) | `codex/answer-effort-ab-20261013` |
|
||||
| `TASK-consult-route-split-20261013.md` | — | consult POST 拆分第一阶段:开流前加载 + 计费结算 | 待领取(排队:consult-prep-parallel、answer-effort-ab) | `codex/consult-route-split-20261013` |
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# TASK · 内测主路径修复单(issue #73,第 1 次打回:与 #63 代码冲突)
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 原任务书:`docs/tasks/TASK-beta-main-path-20261014.md`
|
||||
- 被验 SHA:`fca62fda43b3f8b7bb76303bf0c83427d25c63ee`(`codex/beta-main-path-20261014`)
|
||||
- 执行方:Grok,同一分支续做(merge 最新 `origin/staging`,不改写已推历史)
|
||||
- BUG 编号:沿用 BUG-1063 等本单编号
|
||||
|
||||
## 1. 验收结论:内容通过,与 staging 合并有代码冲突
|
||||
|
||||
| 检查 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 迁移 `20261014010000_chart_profiles_service_role_select.sql` | 通过 | 只加逐列 SELECT,列与 `CHART_SUBJECT_SELECT` 一致;不授写、不改 RLS、不动 authenticated;只增不删,对已部署代码向后兼容(§7.6) |
|
||||
| `test:db` | 以 Grok 为准 | 82 项 / 失败 13,与 `windows-known-failures.txt` 逐名相同 |
|
||||
| AI 生成标识 | 通过 | 输入框下一行、报告标题下一行;英文句只锁不显示 |
|
||||
| 状态板清账 | 通过 | 写「已部署 staging `xxxx`」的 11 个提交号,我逐个核对都在 `origin/staging` 上;未把任何一条标成 resolved |
|
||||
| 与最新 staging 合并 | **未通过** | `CONFLICT (modify/delete): frontend/src/components/personal-report/personal-report-document-view.tsx deleted in origin/staging and modified in HEAD` |
|
||||
|
||||
**原因**:#63(BUG-1342,已在 staging)把从不挂载的旧报告视图 `personal-report-document-view.tsx` 整个删了;本单给它的 `ReportCover` 加了一行 AI 标识。两单同时在做,不是你的疏漏。
|
||||
|
||||
## 2. 修法要求
|
||||
|
||||
1. `git merge origin/staging`,冲突里**接受删除**(`git rm frontend/src/components/personal-report/personal-report-document-view.tsx`)。现行报告页是 `personal-report-markdown-view.tsx`,那里的标识已经加上,不需要再找新位置。
|
||||
2. `frontend/tests/ai-generated-notice-20261014.test.ts` 里若有读取 / 断言该已删文件的,删掉那部分,按 §7.3 写三栏;markdown 视图、输入框的断言保留不动。
|
||||
3. `CHANGELOG.md`、`docs/BUG_HISTORY.md` 的文档冲突两边都保留。
|
||||
4. 合并后在本机跑:`tsc --noEmit`、`npm run lint`、`npx tsx --test tests/ai-generated-notice-20261014.test.ts tests/runtime-sources-no-test-imports.test.ts tests/class-name-definition-contract.test.ts`,fail 与 cancelled 都为 0。
|
||||
5. 业务代码除上面这处外不改。PROGRESS 末尾记一行。
|
||||
|
||||
## 3. 验收标准
|
||||
|
||||
- `git merge-base --is-ancestor origin/staging <新 SHA>` 成立;
|
||||
- Claude 前端全量 `npm test` 失败清单与 staging 基线逐名相同。
|
||||
|
||||
## 4. 让步顺序
|
||||
|
||||
无。第 1 次打回。
|
||||
@@ -0,0 +1,41 @@
|
||||
# TASK · 发问准备并行修复单(issue #62,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 原任务书:`docs/tasks/TASK-consult-prep-parallel-20261013.md`
|
||||
- 被验 SHA:`a0e223e20cebcce3479accb60f6aec44d1caadda`(`codex/consult-prep-parallel-20261013`)
|
||||
- 执行方:Grok,同一分支续做(先 merge 最新 `origin/staging`,不改写已推历史)
|
||||
- BUG 编号:沿用 BUG-1337~1339
|
||||
|
||||
## 1. 验收结论:业务逻辑通过;前端全量多出 3 条真失败
|
||||
|
||||
| 检查 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 开关全关时的顺序 | 通过 | `turn-prep.ts` 串行分支与原 `route.ts` 的 401→423→400→503→404→409→409→503 逐条同序 |
|
||||
| 开关开时 | 通过 | 删号判定仍最先返回、在任何写库扣点之前;审核结论在 `beforeReserve` 内等齐,被拦不 reserve |
|
||||
| `readVersion` 缓存 | 通过 | 只缓存成功结果,`invalidateLanguageModelCatalog` 同时清;默认 TTL 0 |
|
||||
| tsc / lint | 通过 | 0 错 / 0 error |
|
||||
| 前端全量 `npm test`(与 staging 逐名比对) | **未通过:新增 3 条** | 见下 |
|
||||
|
||||
1. `frontend/tests/chat-session-authority.test.ts`「consult POST on a rectification session is 409, a missing id is 404」:第 65 行在 `route.ts` 源码里找 `/if \(!chatSession\) \{[\s\S]*status: 404/`——这段判定挪进了 `frontend/src/lib/consult/turn-prep.ts`(`sessionMissing()`),断言没跟着挪。
|
||||
2. `frontend/tests/consultation-workflow-contract.test.ts`「consultation plans are server-owned and bounded」:第 160 行找 `/beforeReserve: \(\{ consultationMode \}\) => createConsultationPlan\(\{/`,第 161 行找 `reserve: () => reserveConsultationModel(`——两处都改成了 `async` 函数体。
|
||||
3. `frontend/tests/runtime-sources-no-test-imports.test.ts`:`frontend/scripts/research/consult-prep-parallel-ab.mts` 第 9 行从 `../../tests/support/stub-server-only.mjs` 导入。web 镜像不复制 `frontend/tests`,推上 staging 后镜像构建会失败(BUG-1140;#58 刚因同一形状打回过一次)。
|
||||
|
||||
原任务书 §5 第 7 条已经列出要先 grep 的源码文本断言;这次漏的两条不在那份清单里,但属于同一类(AGENTS.md §7.8)。
|
||||
|
||||
## 2. 修法要求
|
||||
|
||||
1. **1、2 两条**:按 §7.3 写「原值 / 新值 / 原因」三栏改断言,**意图不得放宽**:
|
||||
- 1:改为在 `turn-prep.ts` 里锁「查不到会话 → 404」「类型不是 consultation → 409 `session_not_consultation`」,并保留第 70 行那条「不得合并成一个判断」的反向断言(针对新文件)。
|
||||
- 2:改为锁「`beforeReserve` 里调用 `createConsultationPlan`」「`beforeReserve` 在 `reserve` 之前」「`reserve` 调用 `reserveConsultationModel`」,允许 `async` 写法,但不得只查函数名存在。
|
||||
2. **第 3 条**:把 `consult-prep-parallel-ab.mts` 挪到 `frontend/tests/` 下(文件名不得以 `.test.ts` / `.test.tsx` 结尾),导入改相对路径;同步改 PROGRESS 与 `docs/testing/consult-prep-parallel-ab-20261013.md` 里的命令路径。`frontend/scripts/research/` 下其它新增文件同样检查。
|
||||
3. 再 grep 一遍 `route.ts` 被挪走 / 改写的语句在 `frontend/tests`、`tests` 里还有没有按源码文本断言的:`grep -rn "chatSession\.session_type\|getUser()\|refuseWhenAccountDeletionPending\|resolveSessionLanguageModel(\|reserveConsultationModel(\|createConsultationPlan(" frontend/tests tests`,命中的逐条确认。
|
||||
4. 业务代码不改;三个开关默认值不变。
|
||||
|
||||
## 3. 验收标准
|
||||
|
||||
- 前端全量 `npm test` 失败清单与 staging 基线逐名相同(本机另有 Docker 类失败,以基线为准);
|
||||
- `git diff a0e223e2..<新 SHA> -- frontend/src` 为空。
|
||||
|
||||
## 4. 让步顺序
|
||||
|
||||
无。第 1 次打回。
|
||||
@@ -0,0 +1,33 @@
|
||||
# TASK · 前端死代码删除修复单(issue #63,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 原任务书:`docs/tasks/TASK-frontend-dead-code-20261013.md`
|
||||
- 被验 SHA:`1f9947a0d733e34b7754cce058e20b023791fdd8`(`codex/frontend-dead-code-20261013`)
|
||||
- 执行方:Grok,同一分支续做(先 merge 最新 `origin/staging`,不改写已推历史)
|
||||
- BUG 编号:沿用 BUG-1342
|
||||
|
||||
## 1. 验收结论:一条未通过,其余全部通过
|
||||
|
||||
| 检查 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 删除范围 | 通过 | 删掉的文件与三个路由都在原任务书清单内;全仓 grep 三个路由路径、被删模块名,`frontend/src`、`scripts`、`deploy`、`.gitea` 无残留引用 |
|
||||
| 改既有断言 | 通过 | 每处三栏齐全;否定合同(不得挂内部徽章 / 内部面板)保留;`/api/birth-rectification` 改成「路由不存在且无代理」 |
|
||||
| tsc / lint / next build | 通过 | 0 错 / 0 error(warning 125→123)/ `/` 仍 Static;首屏 gzip −312 字节 |
|
||||
| Python 改动的两份测试 | 通过 | — |
|
||||
| 前端全量 `npm test`(与 staging 逐名比对) | **未通过:新增 1 条** | `frontend/tests/class-name-definition-contract.test.ts`「the knownUnstyled allowlist has no stale entries」:`actual: ['personal-report-additional-charts']` |
|
||||
|
||||
**根因**:`class-name-definition-contract.test.ts` 第 62 行的 `knownUnstyled` 白名单里有 `personal-report-additional-charts`,这个类名唯一的使用者是已删除的 `personal-report-document-view.tsx`。合同要求白名单里不能有已经没人用的条目。
|
||||
|
||||
## 2. 修法要求
|
||||
|
||||
1. 从 `knownUnstyled` 删掉 `"personal-report-additional-charts"` 这一项,旁边按 §7.3 写三栏(原值:白名单含该项;新值:删除;原因:唯一使用者随 BUG-1342 删除,白名单不得留陈旧条目)。
|
||||
2. 再查一遍:被删文件里用到的其它类名,是否还出现在别的白名单 / 合同里(`grep -rn "knownUnstyled\|allowlist" frontend/tests` 后逐个核对)。
|
||||
3. 业务代码不改。PROGRESS 末尾记一行。
|
||||
|
||||
## 3. 验收标准
|
||||
|
||||
前端全量 `npm test` 失败清单与 staging 基线逐名相同(本机 Docker 类失败除外)。
|
||||
|
||||
## 4. 让步顺序
|
||||
|
||||
无。第 1 次打回。
|
||||
@@ -0,0 +1,36 @@
|
||||
# TASK · 长报告提速修复单(issue #61,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-14
|
||||
- 原任务书:`docs/tasks/TASK-report-reference-perf-20261013.md`
|
||||
- 被验 SHA:`69c739fbee3f5af6deed911482d82e49ed429bf7`(`codex/report-reference-perf-20261013`)
|
||||
- 执行方:Grok,同一分支续做(先 merge 最新 `origin/staging`,不改写已推历史)
|
||||
- BUG 编号:沿用 BUG-1335、1336
|
||||
|
||||
## 1. 验收结论:本单自身全部通过;与 #60 合并后一条合同测试红
|
||||
|
||||
| 检查 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 与最新 staging 合并后的定向测试 | **未通过** | `tests/test_api_scratch_retention.py::test_new_scratch_local_dirs_are_registered_or_whitelisted`:`AssertionError: ['report_reference_cache']` |
|
||||
| 逐字节一致(Claude 在 Linux、屏蔽 PyJHora 复跑 A/B) | 通过 | 四张虚构盘 A / B 未命中 / B 命中 / 缓存首算的五个字段 sha 全部相同;`format=json`、`edition=reference` 两条 sha 相同 |
|
||||
| 耗时 | 与回报一致 | 未命中中位数 21.1→15.6 s(day)等,降约 22–26%,未到 35% 门槛 → 渲染提速默认关正确;命中 0.02–0.03 s |
|
||||
| 缓存键含 `today` | 通过 | `_high_rigor_birth_payload` 在缺省时把当天日期写进 `birth`,跨天不会命中 |
|
||||
| `GITHUB_SHA` | 通过 | 部署编排已传入;缺失或 `unknown` 时不缓存 |
|
||||
| `jyotish_api_server.py` | 通过 | 零改动 |
|
||||
|
||||
**根因**:#60(BUG-1330~1332,已在 staging)新增了合同测试:`scripts/` 里写 `scratch/local/<子目录>` 的地方,必须登记在 `scripts/api_scratch_retention.py` 的 `REGISTRY`(服务器周期清理)或 `OFFLINE_SCRATCH_NAMES`(自己会清理的缓存)里。本单新增的 `scratch/local/report_reference_cache/` 两边都没登记。两单各自都对,合在一起才红——这不是你的疏漏,是两单同时在做。
|
||||
|
||||
## 2. 修法要求
|
||||
|
||||
1. 合并最新 `origin/staging`(含 #60)。
|
||||
2. 在 `scripts/api_scratch_retention.py::OFFLINE_SCRATCH_NAMES` 加 `"report_reference_cache"`,旁边写一行注释:它与 `consult_full_data_cache` 同走 `consult_full_data_cache.get_or_build`,每次调用先 `prune_cache(name=…)` 删两天前的文件,自己会清;含出生资料,保留期 2 天。
|
||||
3. 不改两个模块的任何逻辑。
|
||||
4. PROGRESS 末尾记一行。
|
||||
|
||||
## 3. 验收标准
|
||||
|
||||
- `python -m pytest tests/test_api_scratch_retention.py tests/test_report_reference_perf.py tests/test_consult_card_full_source.py -q` 全绿;
|
||||
- Claude 全量 pytest 与 staging 基线逐条比对无新增。
|
||||
|
||||
## 4. 让步顺序
|
||||
|
||||
无。第 1 次打回。
|
||||
@@ -0,0 +1,66 @@
|
||||
# 磁盘缓存留存 A/B(2026-10-14)
|
||||
|
||||
对照的是本分支的父提交 `66cd60081f37a57680274633fcb3fb942d01bb2f`(建分支时的 `origin/staging`)。任务书里写的 `77057a819` 已经不是当前测试线头。A 用 `git show` 把父提交的接口文件载入同一进程,并把它的仓库路径指回本工作树,否则临时副本找不到引擎。B 是本分支。
|
||||
|
||||
演练用虚构盘,不写真实出生资料。文件都在系统临时目录,不写工作树里的 `scratch/`。
|
||||
|
||||
主测量挡住了 `jhora` 和 `vedastro` 的导入。本机装了 VedAstro SDK,并且能连上官方端口;另有一组不挡 SDK、但仍关闭外网取数,见文末。
|
||||
|
||||
## 命令
|
||||
|
||||
```powershell
|
||||
.venv\Scripts\python.exe scripts\research\api_chart_cache_byte_diff.py
|
||||
.venv\Scripts\python.exe scripts\research\api_disk_cache_ab.py
|
||||
.venv\Scripts\python.exe scripts\research\api_disk_cache_ab.py --with-sdk --sdk-probe
|
||||
```
|
||||
|
||||
## 命中率
|
||||
|
||||
20 张虚构盘 × 3 种写法 × 快速/完整 × 7 天 × 每种重复 3 次 = 2520 次取键。取键用的是真实缓存键函数,没有把 2520 次都做成完整排盘。
|
||||
|
||||
| | 改前 A | 改后 B | 变化 |
|
||||
| --- | --- | --- | --- |
|
||||
| 不同缓存键 | 840 | 280 | 少 560 |
|
||||
| 命中次数 | 1680 | 2240 | 多 560 |
|
||||
| 命中率 | 0.6667 | 0.8889 | B / A = 1.333 |
|
||||
|
||||
目标是混合写法下 B 至少为 A 的 2.5 倍。按任务书规定的「重复 3 次」算,没有达到:A 自己靠重复就已经有三分之二命中,写法合并只能再抬到约 89%。若不算这 3 次重复、只看三种写法各问一次,A 的命中率是 0,B 是 0.6667。目标数字不改。
|
||||
|
||||
## 七天后的文件
|
||||
|
||||
留存演练写的是短记录,用来数文件,不是完整盘面。期限 900 秒,只有当天的键还没过期。
|
||||
|
||||
| | 改前 A | 改后 B |
|
||||
| --- | --- | --- |
|
||||
| 清理前文件数 | 840 | 280 |
|
||||
| 清理前字节 | 109200 | 36400 |
|
||||
| 清理后文件数 | 840(旧代码没有这份清理) | 40 |
|
||||
| 当天仍有效的键 | 120 | 40 |
|
||||
|
||||
B 清理后的文件数等于当天有效键数,达到「不超过当天活跃键」的目标。
|
||||
|
||||
审计文件:B 在默认关闭时写出 0 个。达到目标。
|
||||
|
||||
负缓存:种入当天和前一天各一份,清理后剩 1 份(当天)。达到目标。
|
||||
|
||||
## 清理耗时
|
||||
|
||||
| 场景 | 结果 |
|
||||
| --- | --- |
|
||||
| 预置 10000 个已过期排盘缓存后,整次清理 | 20.174 秒,排盘目录 20170.902 毫秒,删掉 10000,剩下 0 |
|
||||
| 上面七天演练里的排盘目录 | 370.161 毫秒 |
|
||||
|
||||
目标是 10000 个文件在 2 秒内、且不在请求线程。本次在后台函数里测,不在请求线程;耗时没有进 2 秒。这是 Windows 上逐个读文件再删除的实测,目标不改。默认清理间隔仍是 1800 秒,失败快照短期限仍是 300 秒,不因为这次没进 2 秒就改默认值。
|
||||
|
||||
## 排盘耗时(一次虚构盘,快速排盘,外网关闭)
|
||||
|
||||
| | 中位数 |
|
||||
| --- | --- |
|
||||
| 未命中 3 次 | 23.036 毫秒 |
|
||||
| 命中 3 次 | 5.249 毫秒 |
|
||||
|
||||
## 响应是否还是同一张盘
|
||||
|
||||
数值等价的写法(小时 12 / 12.0 / "12",纬度数字和字符串,时区 5.5 和 "5.5",秒缺省和 0)在快速排盘下去掉 `runtime_cache` 后逐字节相同。完整排盘只差官方快照缓存上的写入时刻和到期时刻,盘面没有别的差异。父提交和本分支对同一张快速排盘、去掉 `runtime_cache` 后逐字节相同。因此这些字段可以合并进同一把缓存键。
|
||||
|
||||
不挡 SDK 的一组:本机有 VedAstro SDK,官方端口能连通。探针仍关闭外网取数。一次完整排盘 4.167 秒,没有报错。没有拉取真实快照。
|
||||
@@ -0,0 +1,36 @@
|
||||
# 发问准备并行:本轮量到的和没量到的(2026-10-14)
|
||||
|
||||
开关都还关着。用户发问后的第一行,这轮不会变快。
|
||||
|
||||
## 进程内假时钟
|
||||
|
||||
命令:`node node_modules/tsx/dist/cli.mjs tests/consult-prep-parallel-ab.mts`(在 `frontend` 目录)。
|
||||
|
||||
假延迟:注销检查 50 毫秒,读会话 80 毫秒,解析模型 80 毫秒。这不是数据库实测。
|
||||
|
||||
| | 逻辑耗时 | 同时进行的步数 |
|
||||
| --- | --- | --- |
|
||||
| 串行 | 210 | 1 |
|
||||
| 并行 | 160 | 2 |
|
||||
|
||||
并行比这三条假延迟的相加更短。它不能代替「首帧中位数下降两成」的开启条件,因为本机没有量 Postgres。
|
||||
|
||||
审核密钥不在这台机器上。测试里把审核挂起 1500 毫秒,第一小段在 400 毫秒内已经写出,然后才收到拦截。这是假等待,不是供应商的真实时间。
|
||||
|
||||
## 版本缓存
|
||||
|
||||
行为测试:15 秒内第二次解析不再查库、不再做地址检查;清缓存后会再查;缓存关掉后每次都查;查库失败和空结果不会被记住。没有量到真实「准备模型」那一段快了多少,所以缓存时间保持 0。
|
||||
|
||||
## 两个领域一起算
|
||||
|
||||
命令:`.venv\Scripts\python.exe frontend\scripts\research\consult-domain-concurrency-ab.py`
|
||||
|
||||
本轮没有启动计算服务,也没有带星盘网络库的镜像。任务书起草时的试算大约只快一成,热缓存时反而更慢,达不到快两成五。默认仍是一个一个算。
|
||||
|
||||
## 仍然关闭的原因
|
||||
|
||||
| 开关 | 现在 | 要打开还缺什么 |
|
||||
| --- | --- | --- |
|
||||
| 发问准备并行 | 关 | 本机 Postgres 上鉴权、注销检查、读会话、读模型各 30 次的中位数,并且首帧中位数至少快两成 |
|
||||
| 模型版本缓存 | 0 毫秒 | 同上,准备模型那一段至少快一半 |
|
||||
| 两个领域一起算 | 1 | 带星盘网络库的镜像上墙钟至少快两成五,争用时 429 不增加,响应除约定字段外一致 |
|
||||
@@ -0,0 +1,61 @@
|
||||
# 长报告出稿 A/B(2026-10-14)
|
||||
|
||||
Windows 本机,Python 3.11.7,`Windows-10-10.0.26200-SP0`。屏蔽 PyJHora(生产镜像不装这个库)。本机本身也没有 PyJHora,所以没有再跑一轮不屏蔽的重复计时。计时开了 tracemalloc,绝对秒数比任务书里的 Linux 基线高,只比较同一进程里的 A 和 B。
|
||||
|
||||
A = 两个开关关。B = 两个开关开。四张虚构盘,每组 3 次。生产请求是完整数据版、markdown、中英都要、带事实表。没有模型钥匙。
|
||||
|
||||
## 端到端(未命中,秒)
|
||||
|
||||
| 盘 | A 三次 | A 中位 | B 三次 | B 中位 | 下降 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| day | 71.31 / 64.03 / 64.01 | 64.03 | 51.05 / 50.77 / 51.74 | 51.05 | 20.3% |
|
||||
| night | 66.25 / 66.11 / 66.66 | 66.25 | 53.32 / 52.57 / 50.43 | 52.57 | 20.7% |
|
||||
| south | 66.03 / 66.00 / 62.69 | 66.00 | 49.97 / 52.79 / 52.68 | 52.68 | 20.2% |
|
||||
| section2 | 71.01 / 108.37 / 74.19 | 74.19 | 57.42 / 57.12 / 71.80 | 57.42 | 22.6% |
|
||||
|
||||
门槛是未命中端到端下降至少 35%。四张盘都没到。渲染快捷路径默认关闭。
|
||||
|
||||
## 分段中位数(秒)
|
||||
|
||||
| 盘 | 中文渲染 A → B | 英文渲染 A → B | 建包 A → B |
|
||||
| --- | --- | --- | --- |
|
||||
| day | 23.55 → 17.04(−27.6%) | 8.27 → 8.67 | 22.55 → 16.08 |
|
||||
| night | 23.42 → 17.19(−26.6%) | 8.75 → 8.41 | 23.70 → 17.21 |
|
||||
| south | 23.89 → 17.39(−27.2%) | 8.66 → 8.74 | 22.90 → 16.87 |
|
||||
| section2 | 22.26 → 17.80(−20.0%) | 8.14 → 8.54 | 31.24 → 21.08 |
|
||||
|
||||
中文渲染门槛是下降至少 40%。没到。没有继续加整篇替换的预检。
|
||||
|
||||
## 内存与字节
|
||||
|
||||
tracemalloc 峰值:B 约为 A 的 0.87 到 0.88,没有升高。
|
||||
|
||||
五份输出(整份响应、中文、英文、事实表、适用性)A、B 未命中、缓存命中的 sha256 全部相同。
|
||||
|
||||
| 盘 | 响应字节 | 响应 sha256 前 12 位 |
|
||||
| --- | --- | --- |
|
||||
| day | 2289867 | 5b542359d606 |
|
||||
| night | 2321638 | 89baa960c054 |
|
||||
| south | 2314369 | 250bf1ab246e |
|
||||
| section2 | 2238092 | 1d7afd481b1a |
|
||||
|
||||
## 同盘缓存(命中,秒)
|
||||
|
||||
| 盘 | 三次 | 中位 |
|
||||
| --- | --- | --- |
|
||||
| day | 0.059 / 0.054 / 0.057 | 0.057 |
|
||||
| night | 0.057 / 0.054 / 0.058 | 0.057 |
|
||||
| south | 0.059 / 0.054 / 0.057 | 0.057 |
|
||||
| section2 | 0.063 / 0.066 / 0.057 | 0.063 |
|
||||
|
||||
命中字节与未命中相同,中位数远低于 1.5 秒。缓存开关默认开。`GITHUB_SHA` 缺失或为 `unknown` 时仍然关。
|
||||
|
||||
## 单次溯源哈希(交付包,秒)
|
||||
|
||||
关:1.132 / 1.099 / 1.115,中位 1.115。开:0.402 / 0.466 / 0.388,中位 0.402。下降 64%,过了 50% 那一档。它跟渲染快捷路径用同一个开关,所以默认也是关。
|
||||
|
||||
## json 与 reference 版
|
||||
|
||||
同一份解盘、时钟钉死后,`format=json` 和 reference 版 markdown 在快捷路径关与开时 sha256 相同(`aa1352619b7a`、`cbadf95f549a`)。对比的是整份响应,没有丢掉字段。
|
||||
|
||||
连续两次重新解盘会对不齐:有的特质列表挂在类上,第二次会再追加。那不是这条快捷路径改出来的。生产要的完整数据 markdown 在多次重算里仍然逐字节相同。
|
||||
Reference in New Issue
Block a user