docs(tasks): 校正标题修补迁移的进度记录与 Bug 历史回填
- PROGRESS-rectification-title-repair-migration-20260916.md:前提复核、 逐字一致的复核命令、幂等两层的说明、基线比对与环境缺口。 - BUG_HISTORY:BUG-699 / BUG-704 的「修复」补记改由迁移承担,「验证」 的欠账改成待产品在 staging 应用后从 NOTICE 回填。不新增编号。 - BLOCKED.md:BLK-002 无 Docker / 无本地 PostgreSQL,test:db 未跑、 db:migrate:check 缺 SCHEMA_DATABASE_URL,附已实跑的替代证据。 - deploy/README.md:一次性数据修补走同一个 Migrate Staging Database 按钮,行数看日志里的 notice 行。 - docs/tasks/README.md:该单改记待验收。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
This commit is contained in:
co-authored by
Claude Opus 5
parent
d6c359b205
commit
10afdcddeb
+4
-4
@@ -10863,8 +10863,8 @@
|
||||
- 用户现象:点开一条以前的生时校正,标题变成今天的日期,并出现在列表最上面。刷新后位置会回去,标题不会。
|
||||
- 触发条件:点侧栏里已有的校正会话,或从首页校正卡打开一条已存在的可续校正。
|
||||
- 根因:复发自 BUG-553。`openRectificationCase` 构造 `merged` 时 `pinned` / `archivedAt` 从 `existing` 继承,`title` 和 `updatedAt` 却无条件用墙钟重算,再 `persistSession` 把标题写回服务端。`persistSession` 的 update 不写 `updated_at`(BUG-553 的修复仍在),所以排序只是客户端暂时错位。BUG-553 的防复发当时只是一句话,测试只锁了元数据 PATCH 和改名/收藏/归档/换模型/换资料,没有覆盖校正 open。
|
||||
- 修复:已有会话的 `title` / `updatedAt` 继承 `existing`,只有新建才 `resolveSessionTitle` + `timestamp()`。错日期标题按 `created_at` 的 Asia/Shanghai 月日修回;对不上正则的手改标题不动。
|
||||
- 验证:`frontend/tests/session-open-preserves-identity.test.ts`、`rectification-session-title-repair.test.ts`。浏览器级验收见 `docs/testing/rectification-open-identity-20260915.md`。staging 标题修回行数见本单 PROGRESS。
|
||||
- 修复:已有会话的 `title` / `updatedAt` 继承 `existing`,只有新建才 `resolveSessionTitle` + `timestamp()`。错日期标题按 `created_at` 的 Asia/Shanghai 月日修回;对不上正则的手改标题不动。存量错标题的修补已改为一次性迁移 `20260916020000_rectification_session_title_repair.sql`,随 `Migrate Staging Database` 按钮应用(原先只写在 `frontend/scripts/repair-rectification-session-titles.mjs` 里,要 `SCHEMA_DATABASE_URL` 才能跑,产品没有执行通道,所以一次都没跑过);该脚本降级为只读核对工具。
|
||||
- 验证:`frontend/tests/session-open-preserves-identity.test.ts`、`rectification-session-title-repair.test.ts`、`rectification-session-title-repair-migration.test.ts`(比对迁移与核对脚本的 SQL 是否仍逐字一致)。浏览器级验收见 `docs/testing/rectification-open-identity-20260915.md`。**欠账**:staging 标题修回行数待产品点一次 `Migrate Staging Database` 后,从运行日志的 `notice ... repaired_titles=` 回填。无 Docker 环境跑不了 `npm run test:db`,迁移未实跑过。
|
||||
- 防复发:构造可能作用于已有会话的 `ChatSession` 时,不得无条件写 `updatedAt: timestamp()`。`resolveSessionTitle` 的 `at` 默认墙钟,只能用于新建。
|
||||
- 相关记录:BUG-553、BUG-704、BUG-705
|
||||
- 复发自:BUG-553
|
||||
@@ -10943,8 +10943,8 @@
|
||||
- 用户现象:一条校正连着答几小时,侧栏位置仍停在创建那天。叠加上被改成今天的标题后,列表变成「名字是今天、排序是旧日期」。
|
||||
- 触发条件:在生时校正里写 turn、点选、采用或停止。打开、刷新、改名、收藏不触发。
|
||||
- 根因:复发自 BUG-553 的另一半。全仓只有咨询 RPC `append_consultation_question` 写 `chat_sessions.updated_at`。校正 turn 走 `append_agentic_rectification_turn` 等,只推 `agentic_rectification_cases.last_activity_at`,不碰会话表。`persistSession` 的 update 按 BUG-553 故意不写 `updated_at`。
|
||||
- 修复:`last_activity_at` 推进时触发器同步把对应校正会话的 `updated_at` 推到同一时刻,且不得回拨。历史冻结行按最后一条 turn / `last_activity_at` 回填。客户端 `persistSession` 仍不写 `updated_at`。
|
||||
- 验证:`frontend/tests/rectification-v9-migration.test.ts` 的 touch-session 迁移合同。浏览器级见 `docs/testing/rectification-open-identity-20260915.md`。staging 回填行数见本单 PROGRESS。
|
||||
- 修复:`last_activity_at` 推进时触发器同步把对应校正会话的 `updated_at` 推到同一时刻,且不得回拨。历史冻结行按最后一条 turn / `last_activity_at` 回填,该回填同样已改为一次性迁移 `20260916020000_rectification_session_title_repair.sql`(与 BUG-699 的标题修补同一条),随 `Migrate Staging Database` 应用;`updated_at <` 的单调守卫保证只前进不回拨,重复应用影响 0 行。客户端 `persistSession` 仍不写 `updated_at`。
|
||||
- 验证:`frontend/tests/rectification-v9-migration.test.ts` 的 touch-session 迁移合同、`rectification-session-title-repair-migration.test.ts` 的回填 SQL 合同。浏览器级见 `docs/testing/rectification-open-identity-20260915.md`。**欠账**:staging 回填行数待产品点一次 `Migrate Staging Database` 后,从运行日志的 `notice ... refreshed_activity=` 回填。无 Docker 环境跑不了 `npm run test:db`,迁移未实跑过。
|
||||
- 防复发:校正对话活动必须推进 `chat_sessions.updated_at`。元数据 PATCH、打开、刷新不得推进。不得为了修这个让 `persistSession` 重新写 `updated_at`。
|
||||
- 相关记录:BUG-553、BUG-699、BUG-705
|
||||
- 复发自:BUG-553
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
# PROGRESS · 把会话标题/活跃时间修补做成迁移
|
||||
|
||||
- 日期:2026-09-16
|
||||
- 任务书:`docs/tasks/TASK-rectification-title-repair-migration-20260915.md`
|
||||
- 分支:`codex/rectification-title-repair-migration-20260916`
|
||||
- 实际基线:`origin/staging` @ `37e6c519`(任务书写的 `e7016551` 早已被超车,前提已逐条复核,见 §1)
|
||||
- 未推 staging,按指派只提交到本分支,验收与合入由指派方做。
|
||||
|
||||
---
|
||||
|
||||
## 1. 开工前的前提复核(结论:前提全部成立)
|
||||
|
||||
| 任务书的前提 | 复核方式 | 结论 |
|
||||
| --- | --- | --- |
|
||||
| 修补脚本仍在 | `frontend/scripts/repair-rectification-session-titles.mjs` | 在,3601 字节 |
|
||||
| 脚本仍是纯 SQL,Node 只连库/打印 | 通读全文 | 成立:`TITLE_MATCH_SQL` / `TITLE_APPLY_SQL` / `ACTIVITY_APPLY_SQL` 全是 SQL 字符串 |
|
||||
| 数据还没被别的轮次修过 | `frontend/supabase/migrations/` 下无对应迁移 | 成立,无人做过 |
|
||||
| where 条件对得上当前 schema | 逐列核对 | 成立,见下 |
|
||||
| 标题格式没变 | `frontend/src/lib/agent-reply.ts` 的 `datedSessionTitle` | 成立,仍是 `M月D日 · 生时校正`,`uniquifySessionTitle` 仍可追加 ` HH:MM`,与脚本正则完全对应 |
|
||||
|
||||
schema 逐列核对:`chat_sessions` 的 `title` / `created_at` / `updated_at` / `user_id` 在 `20260715030000`,`session_type` 在 `20260721110000`(取值仍含 `birth_time_rectification`);`agentic_rectification_cases` 的 `session_id` / `user_id` / `last_activity_at` 与 `agentic_rectification_turns` 的 `case_id` / `created_at` 在 `20260812010000`。全部仍在。
|
||||
|
||||
另外两件影响正确性、任务书没提、我主动核过的事:
|
||||
|
||||
1. **UPDATE 不会误触发触发器。** `chat_sessions` 上只有两个触发器,`chat_sessions_default_rectification_model` 与 `chat_sessions_pin_model_config_version`,都是 `before insert or update of <指定列>`(`session_type` / `model_id` / `model_config_version`)。本迁移只写 `title` 与 `updated_at`,两个都不触发。
|
||||
2. **没有自动 `updated_at` 触发器。** 所以标题那段 update 不会顺带把 `updated_at` 推成今天、把会话顶到侧栏最前——那正是 BUG-699 的现象本身,踩上就等于一边修一边复发。
|
||||
|
||||
---
|
||||
|
||||
## 2. 做了什么
|
||||
|
||||
### 2.1 新增迁移(任务 1)
|
||||
|
||||
`frontend/supabase/migrations/20260916020000_rectification_session_title_repair.sql`
|
||||
|
||||
- 时间戳排在当前最后一条 `20260916010000_consultation_session_capacity.sql` 之后。
|
||||
- 权限守卫沿用 `20260915010000` 的写法:`current_user <> 'schema_owner'` 就 `raise exception`,errcode `42501`。
|
||||
- 两段 update 放在一个 `do $repair$` 块里,各自 `get diagnostics ... = row_count` 后 `raise notice` 打出行数。
|
||||
- 顺序与脚本一致:先标题,后活跃时间。
|
||||
|
||||
**SQL 逐字一致是机器保证的,不是我说的。** 迁移的 SQL 不是手敲的,是用 `sed` 从脚本里按行切出来拼进去的;随后
|
||||
`frontend/tests/rectification-session-title-repair-migration.test.ts` 把脚本导出的三个常量与迁移正文比对(只做行尾空白归一化,因为脚本拼的是 `where ${TITLE_MATCH_SQL}`,会留一个 `.sql` 文件不该有的行尾空格)。以后改了任何一边而没同步另一边,这条测试就红。
|
||||
|
||||
复核者可以自己再验一遍:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
diff <(sed -n '38,45p' supabase/migrations/20260916020000_rectification_session_title_repair.sql) \
|
||||
<(sed -n '35,42p' scripts/repair-rectification-session-titles.mjs) # TITLE_APPLY
|
||||
diff <(sed -n '47,55p' supabase/migrations/20260916020000_rectification_session_title_repair.sql) \
|
||||
<(sed -n '21,29p' scripts/repair-rectification-session-titles.mjs) # TITLE_MATCH
|
||||
diff <(sed -n '59,70p' supabase/migrations/20260916020000_rectification_session_title_repair.sql) \
|
||||
<(sed -n '62,73p' scripts/repair-rectification-session-titles.mjs) # ACTIVITY_APPLY
|
||||
```
|
||||
|
||||
三个 diff 都是空的。Asia/Shanghai 时区、正则、`case`、`coalesce(turns.last_turn_at, case_row.last_activity_at)`、`updated_at <` 单调守卫,一个字都没动。
|
||||
|
||||
### 2.2 幂等性怎么保证的
|
||||
|
||||
两层,互相独立:
|
||||
|
||||
1. **迁移器层**:`migration.schema_migrations` 以文件名为主键记账,`db-migrate.mjs` 见到已记账的文件就 `already applied ... continue`。正常路径下这条迁移一辈子只执行一次。
|
||||
2. **SQL 自身**(真正兜底的一层,防的是有人手工重放):
|
||||
- 标题:改完之后,`title` 里的月日就等于 `created_at` 的 Asia/Shanghai 月日,`is distinct from` 两个条件同时为假;`created_at is null` 的行被改成不带日期的 `生时校正`,连 `title ~ '^[0-9]{1,2}月...'` 正则都不再匹配。where 整体不再命中这些行。
|
||||
- 活跃时间:改完之后 `session.updated_at` 恰好等于 `coalesce(turns.last_turn_at, case_row.last_activity_at)`,`<` 为假。`<` 同时也是单调守卫,任何情况下只前进不回拨。
|
||||
|
||||
所以重复应用影响 0 行,`RAISE NOTICE` 会打出 `repaired_titles=0` / `refreshed_activity=0`。
|
||||
|
||||
### 2.3 一处任务书没写、但不补就等于白做的改动
|
||||
|
||||
任务书 §5 任务 1.4 说「`RAISE NOTICE` 打出的行数会出现在 `Migrate Staging Database` 的日志里——这是产品唯一能看到数字的地方」。**照原样实现的话,那个数字不会出现。**
|
||||
|
||||
staging 的 migrator 服务跑的是 `npm run db:migrate` → `frontend/scripts/db-migrate.mjs`,用的是 node-postgres。node-postgres 把 NOTICE 作为 Client 的 `notice` 事件抛出,**没有监听器就直接丢掉**,既不报错也不打印。原来的 `db-migrate.mjs` 全文没有 `notice` 二字。
|
||||
|
||||
所以在 `runMigrations` 里加了 4 行 notice 转发,把 NOTICE 打成 `notice <message>` 走既有 `logger`。这不是顺手改别的东西,是任务 1.4 的落地前提;没有它,产品点完按钮看到的是一片空白。
|
||||
|
||||
边界都守住了:没动 `deploy/run-staging-migration.sh`、没动 `deploy/docker-compose.postgres.yml`、没动任何 `.gitea/workflows/**`(任务书硬红线 2)。迁移仍由**现有** migrator 原样应用。没有测试断言过 migrator 的日志行,只有 `tests/model-configuration-security.test.ts` 传了个 `logger: console` 进去,不校验输出。
|
||||
|
||||
### 2.4 脚本降级为只读核对(任务 2)
|
||||
|
||||
`frontend/scripts/repair-rectification-session-titles.mjs`:
|
||||
|
||||
- 文件头注明修补已由迁移承担,本文件只用于核对,并指名那条迁移。
|
||||
- `--apply` 不再写库,直接报错并指向迁移与 `Migrate Staging Database` 按钮(实测退出码 1)。
|
||||
- 保留两段 count 查询;**文件没删**(任务书 2.2)。
|
||||
- 三个 SQL 常量改为 `export`,让它成为迁移的唯一出处、并被合同测试读取——顺带也让它们不再是 lint 眼里的死变量。
|
||||
- 加了 `invokedPath === import.meta.url` 守卫。原来第 95 行的 `main().catch(...)` 是无条件执行的,`import` 这个文件就会去连库;合同测试要导入它,不加这个守卫测试会去连数据库。
|
||||
|
||||
---
|
||||
|
||||
## 3. 验证
|
||||
|
||||
| 项 | 命令 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 类型 | `./node_modules/.bin/tsc --noEmit` | **0 错** |
|
||||
| lint | `npm run lint` | **0 error**(120 warning,全部在本轮未改的文件里;`scripts/db-migrate.mjs`、`scripts/repair-rectification-session-titles.mjs`、新测试三者 0 条) |
|
||||
| 新合同测试 | `npx tsx --test tests/rectification-session-title-repair-migration.test.ts` | **5/5 通过** |
|
||||
| 全量测试(本分支) | `npm test` | tests **3334** / pass 3288 / **fail 31** / skipped 15 |
|
||||
| 全量测试(基线) | 同一工作树 detach 到 `origin/staging` @ `37e6c519` 后 `npm test` | tests **3329** / pass 3283 / **fail 31** / skipped 15 |
|
||||
| 迁移文件级校验 | 假连接串调 `runMigrations({check:true})` | 报错停在 `connect ECONNREFUSED`,说明文件名正则/重复检查/目录扫描都过了 |
|
||||
| `db:migrate:check` | `npm run db:migrate:check --prefix frontend` | **未通过——环境缺口**,见 §4 |
|
||||
| `test:db` | `npm run test:db --prefix frontend` | **没跑——无 Docker**,见 §4 |
|
||||
|
||||
基线比对结论:本轮**净增 5 个测试且全绿,31 条失败一条不多一条不少**,测试总数只增不减,没有改写或弱化任何既有断言。
|
||||
|
||||
CLI 行为实测:
|
||||
|
||||
```
|
||||
$ node scripts/repair-rectification-session-titles.mjs --apply
|
||||
--apply has been removed; the repair now ships as migration 20260916020000_rectification_session_title_repair.sql. Apply it with Gitea -> Migrate Staging Database.
|
||||
exit=1
|
||||
$ node scripts/repair-rectification-session-titles.mjs
|
||||
SCHEMA_DATABASE_URL is required
|
||||
exit=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 环境缺口(不得记成通过)
|
||||
|
||||
本机**没有 Docker**(`docker info` 失败),**也没有本地 PostgreSQL**(`which psql postgres pg_ctl initdb` 全空)。因此:
|
||||
|
||||
- `npm run test:db --prefix frontend` 没跑。
|
||||
- `npm run db:migrate:check --prefix frontend` 在连库之前就以 `SCHEMA_DATABASE_URL is required` 退出 1,拿不到 pending 清单。这是缺库缺口,不是迁移本身有问题——同一入口的文件级校验已单独走通(见 §3)。
|
||||
- **这条迁移的 SQL 从未在真实 PostgreSQL 上执行过**(它原本所在的脚本也一次都没跑过)。静态旁证是三种写法在已应用的迁移里都有先例:`update public.chat_sessions as session`(`20260808030000`、`20260901010000`)、`join lateral`(`20260814020000` 等)、`get diagnostics ... = row_count`(`20260811020000`)。旁证不等于实跑。
|
||||
|
||||
已登记为 `BLOCKED.md` 的 **BLK-002**。真实证据只能由产品在 staging 点一次按钮后回填。
|
||||
|
||||
---
|
||||
|
||||
## 5. 产品侧下一步
|
||||
|
||||
1. 等门禁转绿、`Deploy Staging` 发上去。
|
||||
2. Gitea →`Migrate Staging Database`→ 填那个 SHA → 运行。
|
||||
3. 在日志里找这两行,就是修了多少行:
|
||||
|
||||
```
|
||||
notice rectification_session_title_repair repaired_titles=<n>
|
||||
notice rectification_session_title_repair refreshed_activity=<n>
|
||||
```
|
||||
|
||||
4. 刷新页面,看历史校正会话的名字是否恢复成真实日期。
|
||||
5. 把两个数字回填进 `docs/BUG_HISTORY.md` 的 BUG-699 / BUG-704「验证」段,并划掉 `BLOCKED.md` 的 BLK-002。
|
||||
|
||||
生产停在 `7b620c7a`,没有 `use-rectification-surface.ts`,标题固定为「生时校正」且不写库,两段 where 自然匹配 0 行。**将来这条随 `main` 提升进生产时打出 `repaired_titles=0` 是预期结果,不是失败。**
|
||||
|
||||
---
|
||||
|
||||
## 6. 没做的事
|
||||
|
||||
- 没推 `staging`,没碰 `main`。
|
||||
- 没动 `deploy/run-staging-migration.sh`、`deploy/docker-compose.postgres.yml`、任何 `.gitea/workflows/**`。
|
||||
- 没改任何前端行为:`src/` 一行未动。
|
||||
- 没动 `CHANGELOG.md`(任务书 3.2:用户可见行为不变)。
|
||||
- 没新增 BUG 编号(任务书 3.2:这是交付通道补齐,不是新缺陷)。
|
||||
- 没把迁移复制进 `frontend/db/migrations/`(BUG-127 / BUG-144,新测试里有断言)。
|
||||
@@ -228,7 +228,7 @@
|
||||
| `TASK-ephemeris-page-20260915.md` | `PROGRESS-ephemeris-page-20260915.md` | **前端单**:P1 星历页,今日五要素 + 当日行运(相对本命宫位)+ 未来九十天换座与停滞,底部「带这天去提问」出口。页面不得出现任何运势判断。含实证缺陷:panchanga 写死 Lahiri 与账户 Raman 分裂(关联 BUG-703;本单标注为 BUG-707)。侧边栏入口由 chart-page 单交付。BUG 段 707–709 | 已验收(带修复单) | `d3a2c48b` |
|
||||
| `TASK-readonly-pages-fix-20260916.md` | `PROGRESS-readonly-pages-fix-20260916.md` | 三份只读页单的验收修复:**BUG-710** 七政 `ketu_mode`/`sidereal_mode` 收了请求却从不传给引擎,`calculation.ketu_mode` 回写请求值而非实际值(实测请求 descending-node 仍返回 apogee 盘,无警告);**BUG-711** 星历单断言 sidebar 不得含 `/ephemeris`,与星盘单按任务书添加的入口直接冲突,staging 现在是红的;**BUG-712** `ephemeris_events` golden 存全精度浮点跨机不稳,且 golden 缺失时自动重建。另附部署缺口:`deployment.gitCommit` 仍是 `2d7698ea`。BUG 段 710+ | 待验收 | `codex/readonly-pages-fix-20260916` |
|
||||
| `TASK-chart-page-blocking-open-20260915.md` | `PROGRESS-chart-page-blocking-open-20260915.md` | **P1**:星盘页开一次要等很久且常常只给一句「过一会儿再打开」。实测引擎五个调用合计 0.75 秒、mapper 13 种形态零抛出——瓶颈在 `/chart` 是动态路由 + 侧栏改成硬文档跳转,整页 SSR 等完 1 串 4 并才开始画,白屏最长 45 秒(BUG-716);`postEngine` 把 429/500/超时/坏 JSON 全碾成 `null` 且零日志,两种性质相反的故障共用一句文案(BUG-715);开页并行打两个重计算限流端点(配额 2)、无缓存,且「打开即有」印在失败页上(BUG-717)。**串行在 readonly-pages-fix 之后** | 待验收 | `codex/chart-page-blocking-open-20260915` |
|
||||
| `TASK-rectification-title-repair-migration-20260915.md` | — | BUG-699 / 704 的数据修补写成了 Node 脚本(要 `SCHEMA_DATABASE_URL`),但 `Migrate Staging Database` 只跑 `migrator` 应用 SQL 迁移、不执行任意脚本——产品没有任何按钮能修自己那批错名字的会话。脚本里本来就是纯 SQL,搬进一次性迁移即可复用现成按钮。生产停在 `7b620c7a`(无 `use-rectification-surface.ts`),where 自然匹配 0 行,是 no-op | 待领取 | `codex/rectification-title-repair-migration-20260915` |
|
||||
| `TASK-rectification-title-repair-migration-20260915.md` | `PROGRESS-rectification-title-repair-migration-20260916.md` | BUG-699 / 704 的数据修补写成了 Node 脚本(要 `SCHEMA_DATABASE_URL`),但 `Migrate Staging Database` 只跑 `migrator` 应用 SQL 迁移、不执行任意脚本——产品没有任何按钮能修自己那批错名字的会话。脚本里本来就是纯 SQL,搬进一次性迁移即可复用现成按钮。生产停在 `7b620c7a`(无 `use-rectification-surface.ts`),where 自然匹配 0 行,是 no-op | 待验收(`d6c359b2`,分支 `codex/rectification-title-repair-migration-20260916`):迁移 `20260916020000_rectification_session_title_repair.sql`,SQL 由 `sed` 从脚本切出、合同测试比对逐字一致;幂等两层(迁移器记账 + where 改完即不再命中);顺带给 `db-migrate.mjs` 加 NOTICE 转发,否则 node-postgres 丢掉 NOTICE、产品在日志里一个数字都看不到。tsc 0 错、lint 0 error、`npm test` 3334/fail 31 对基线 3329/fail 31(+5 全绿)。**无 Docker/无本地 PG**:`test:db` 没跑、`db:migrate:check` 缺 `SCHEMA_DATABASE_URL`,记为 BLK-002 | `codex/rectification-title-repair-migration-20260916` |
|
||||
| `TASK-staging-dispatch-autofill-sha-20260915.md` | `PROGRESS-staging-dispatch-autofill-sha-20260915.md` | `Migrate Staging Database` 每次都要手抄 40 位 SHA,而那个值恰恰是「最新一个过门禁的 staging 提交」——机器能自己算,查询代码那一步里就有。改成留空自动解析、填了仍走原路径(回滚用),三条安全属性一条不丢。**产品 2026-09-15 明确授权修改该 workflow,执行方不得以 AGENTS.md §2.7 拒改**;生产两个按钮保持手填,那是护栏不是麻烦 | 待验收 | `codex/staging-dispatch-autofill-sha-20260915` |
|
||||
| `TASK-staging-auto-migrate-on-deploy-20260915.md` | `PROGRESS-staging-auto-migrate-on-deploy-20260915.md` | 门禁通过后自动先跑 staging 迁移再部署,不再手点(迁移幂等、无挂起时是 no-op,`db-migrate.mjs --check` 挂起返 3 可用于日志)。今天 `deploy-staging.yml` 完全不提迁移,忘点就让新代码跑在旧 schema 上且无人拦。**产品再次授权改 workflow,范围限 `backend-quality-gate.yml` 的 dispatch 段**;迁移失败必须阻断部署;回滚不自动迁移;生产完全不动。⚠️ 同轮必须把「迁移须对已部署代码向后兼容、破坏性变更拆两轮」写进 AGENTS.md §7.6 | 待验收 | `codex/staging-auto-migrate-on-deploy-20260915` |
|
||||
| `TASK-api-server-decomposition-20260916.md` | `PROGRESS-api-server-decomposition-20260916.md` | **已取代:阶段 1 由 `TASK-api-server-backdoor-close-20260916` 完成(实测只需 8 方法 / 314 行);阶段 2/3 产品拍板不立单,由新门禁长期推进。以下为原文** · 重构单(串行在 qizheng 单之后;2026-09-15 又加两条前置:C1 外网缓存单先做、freeze-metric-change 先落地)**:把业务逻辑搬出 `JyotishAPIHandler`。核心不是行数,是 3 个文件 **4 处**靠 `JyotishAPIHandler.__new__` 伪造空壳 handler 借方法(`consultation_workflow_service` ×2、`capture_report_blocked_repairs_golden`、`local_accuracy_report`,MCP 也走这条),依赖方向反了、handler 没有 `headers`/`wfile` 随时可炸——实测佐证:**225 个类方法里只有 12 处真的碰 HTTP 上下文**。四阶段:拆 `__new__` 后门 → 抽 ≥150 行业务方法 → `do_POST`/`do_GET` 改路由表 → **阶段 4 已改写**:收尾不再是「行数 baseline + 余量 300→50」(那只是把问题推到三个月后),改成主门 `__new__` 计数必须为 0 + 类方法数不得增长,行数退为粗护栏保持 300 余量。纯搬运不改行为,`test_api_server_security.py` 3841 行断言一条不许改。预计 11,334 → 约 9,230 行。BUG 段 710+ | 已取代 | 见 `TASK-api-server-backdoor-close-20260916.md` |
|
||||
|
||||
Reference in New Issue
Block a user