knownUnstyled 不再保留 personal-report-additional-charts。它只被删掉的报告组件用过。其它白名单没有同类残留。业务代码没改。 自测:类名合同和两条否定合同 6 通过,失败 0,取消 0。tsc 0 错,lint 0 error。 Co-Authored-By: Grok (agent loop)
244 lines
15 KiB
Markdown
244 lines
15 KiB
Markdown
# 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。
|