diff --git a/.doc/archive/ops/2026-09-20-p0-hotfixes.md b/.doc/archive/ops/2026-09-20-p0-hotfixes.md new file mode 100644 index 00000000..48ddab2e --- /dev/null +++ b/.doc/archive/ops/2026-09-20-p0-hotfixes.md @@ -0,0 +1,49 @@ +--- +title: "2026-09-20 P0 热修(迁移 / 越权 / 稳定性 / 凭证)" +status: done +created: 2026-09-20 +updated: 2026-09-20 +owner: Cursor-Auto +branch: docs/p0-closeout-2026-09-20 +worktree: "-" +mutex: docs +--- + +# 2026-09-20 P0 热修 + +## 目标 + +关闭系统体检发现的 P0 critical:迁移断链、三项 IDOR、进程 panic/race、凭证泄漏与生产口令轮换。 + +## 范围 + +- Wave 0–4(见 [整改方案](../../remediation/2026-09-20-p0-remediation-plan.md)) +- 后续实现分支:`fix/capability-merge-00058-2026-09-20`、`fix/authz-idor-hotfixes-2026-09-20`、`fix/runtime-panic-races-2026-09-20`、`fix/credential-hardening-2026-09-20`、`docs/p0-closeout-2026-09-20` + +## 非目标 + +- main 分支对齐晋升 +- FAV / SWBOOT-10 / D7 / MULTI_INTENT full + +## 步骤 + +1. [x] Wave 0:审计与整改文档、CURRENT 认领、long-term 增补 +2. [x] Wave 1:capability 合入 + 00058 + rebuild +3. [x] Wave 2:三项越权 +4. [x] Wave 2b:panic/race/recover/XSS +5. [x] Wave 3:凭证 + 口令轮换 +6. [x] Wave 4:测试报告与收口 + +## 验收标准 + +- [x] 见 [测试报告](../../test-reports/2026-09-20-p0-hotfixes-test-report.md) + +## 相关链接 + +- Audit: [../../audit/2026-09-20-system-triage-audit.md](../../audit/2026-09-20-system-triage-audit.md) +- Remediation: [../../remediation/2026-09-20-p0-remediation-plan.md](../../remediation/2026-09-20-p0-remediation-plan.md) +- Test report: [../../test-reports/2026-09-20-p0-hotfixes-test-report.md](../../test-reports/2026-09-20-p0-hotfixes-test-report.md) + +## 证据 / 备注 + +(各波次合入 commit 与健康输出) diff --git a/.doc/ops/CURRENT.md b/.doc/ops/CURRENT.md index 390a3344..477c8522 100644 --- a/.doc/ops/CURRENT.md +++ b/.doc/ops/CURRENT.md @@ -1,11 +1,11 @@ # 当前焦点 **更新**: 2026-09-20 -**production_ready**: yes(门禁 B1–B4 已签;实测 dev/test schema **57**、main **52**。P0 热修进行中:迁移 00058 / IDOR / panic / 凭证。不把 fallback change report 写成完整 PI) +**production_ready**: yes(门禁 B1–B4 已签;dev/main schema **58**、test **57**。P0 热修 done;见 [报告](../test-reports/2026-09-20-p0-hotfixes-test-report.md)。不把 fallback change report 写成完整 PI) ## 焦点 -1. **2026-09-20 P0 系统体检热修 in_progress**:迁移断链(capability→00058)、三项 IDOR、taskrun panic/race、凭证脚本 + main 口令轮换;见 [审计](../audit/2026-09-20-system-triage-audit.md) · [整改](../remediation/2026-09-20-p0-remediation-plan.md) · [short-term](./short-term/2026-09-20-p0-hotfixes.md)。 +1. **2026-09-20 P0 系统体检热修 done**:迁移 00058、三项 IDOR、panic/race/XSS、凭证轮换;见 [报告](../test-reports/2026-09-20-p0-hotfixes-test-report.md) · [审计](../audit/2026-09-20-system-triage-audit.md)。 2. **2026-09-20 激活后职责改派 + 成员可对话 done**:合入 `9d98f1ae`;test rebuild;陈威 chat PASS、PATCH 改派 PASS;见 [报告](../test-reports/2026-09-20-post-activation-duty-reassign-member-chat-test-report.md)。 3. **2026-09-20 test 环境三问题整改 done**:全局项目名唯一、成员会话可见、资产 raw 预览回退;test schema **57**;见 [报告](../test-reports/2026-09-20-test-env-triage-fixes-test-report.md)。 4. **红线**:禁止整支 merge FAV;不默认升 `MULTI_INTENT_PLAN_TIER=full`;`SEMANTIC_SUMMARY_REPLACE` 不随 W2 开启;FAV live 观察窗证据驱动;`FAV_DEGRADED_READ=false`;项目 143 只读;SWBOOT-10 保持 fail-closed stub;D7 待合规签字;**P0 期间不改 `production_ready`** @@ -14,11 +14,12 @@ | owner | task | branch | worktree | mutex | status | |-------|------|--------|----------|-------|--------| +| Cursor-Auto | 2026-09-20-p0-closeout | docs/p0-closeout-2026-09-20 | - | docs | done | | Cursor-Auto | 2026-09-20-p0-hotfixes(Wave 0 文档) | docs/p0-triage-2026-09-20 | - | docs | done | | Cursor-Auto | 2026-09-20-p0-capability-00058 | fix/capability-merge-00058-2026-09-20 | - | infra+chat | done | | Cursor-Auto | 2026-09-20-p0-idor | fix/authz-idor-hotfixes-2026-09-20 | - | authz | done | | Cursor-Auto | 2026-09-20-p0-runtime-stability | fix/runtime-panic-races-2026-09-20 | - | taskrun+chat+web | done | -| Cursor-Auto | 2026-09-20-p0-credentials | fix/credential-hardening-2026-09-20 | - | ops+infra | in_progress | +| Cursor-Auto | 2026-09-20-p0-credentials | fix/credential-hardening-2026-09-20 | - | ops+infra | done | | Cursor-Auto | 2026-09-20-proposed-authoritative-reports | feature/capability-enablement-impact-plan | - | docgov | done | | Cursor-Auto | 2026-09-20-pi-narrative-clipped-diff | feature/capability-enablement-impact-plan | - | docgov | done | | Cursor-Auto | 2026-09-20-pi-reasoning-profile | feature/capability-enablement-impact-plan | - | pi-agent | done | @@ -165,7 +166,7 @@ | holder | phase | since | scope | queue | |--------|-------|-------|-------|-------| -| Cursor-Auto | merging | 2026-09-20 | fix/credential-hardening | - | +| - | idle | 2026-09-20 | P0 全波合入 + 报告归档;槽位释放 | - | **phase**: `idle` | `merging` | `smoke` | `e2e` @@ -176,7 +177,7 @@ | 环境 | 端口 | schema | 状态 | |------|------|--------|------| | dev | 8080 | **58** | healthy(`chat_summaries` 已落地;`pi-agent`;events `:8088`) | -| test | 8081 | **57** | healthy(含 triage `00057`;分支树最高仍可能为 56——晋升前须对齐;events `:8089`) | +| test | 8081 | **57** | healthy(待下次晋升补 00058;events `:8089`) | | main | 8000 | **58** | healthy(P0 Wave3 rebuild 已追平 schema;分支树对齐仍记 backlog;口令已轮换;events `:8090`) | ## SSOT diff --git a/.doc/ops/short-term/2026-09-20-p0-hotfixes.md b/.doc/ops/short-term/2026-09-20-p0-hotfixes.md index 6bb230bf..48ddab2e 100644 --- a/.doc/ops/short-term/2026-09-20-p0-hotfixes.md +++ b/.doc/ops/short-term/2026-09-20-p0-hotfixes.md @@ -1,10 +1,10 @@ --- title: "2026-09-20 P0 热修(迁移 / 越权 / 稳定性 / 凭证)" -status: in_progress +status: done created: 2026-09-20 updated: 2026-09-20 owner: Cursor-Auto -branch: docs/p0-triage-2026-09-20 +branch: docs/p0-closeout-2026-09-20 worktree: "-" mutex: docs --- @@ -28,21 +28,21 @@ mutex: docs ## 步骤 1. [x] Wave 0:审计与整改文档、CURRENT 认领、long-term 增补 -2. [ ] Wave 1:capability 合入 + 00058 + rebuild -3. [ ] Wave 2:三项越权 -4. [ ] Wave 2b:panic/race/recover/XSS -5. [ ] Wave 3:凭证 + 口令轮换 -6. [ ] Wave 4:测试报告与收口 +2. [x] Wave 1:capability 合入 + 00058 + rebuild +3. [x] Wave 2:三项越权 +4. [x] Wave 2b:panic/race/recover/XSS +5. [x] Wave 3:凭证 + 口令轮换 +6. [x] Wave 4:测试报告与收口 ## 验收标准 -- [ ] 见整改方案验收清单 +- [x] 见 [测试报告](../../test-reports/2026-09-20-p0-hotfixes-test-report.md) ## 相关链接 - Audit: [../../audit/2026-09-20-system-triage-audit.md](../../audit/2026-09-20-system-triage-audit.md) - Remediation: [../../remediation/2026-09-20-p0-remediation-plan.md](../../remediation/2026-09-20-p0-remediation-plan.md) -- Test report: (Wave 4) +- Test report: [../../test-reports/2026-09-20-p0-hotfixes-test-report.md](../../test-reports/2026-09-20-p0-hotfixes-test-report.md) ## 证据 / 备注 diff --git a/.doc/remediation/2026-09-20-p0-remediation-plan.md b/.doc/remediation/2026-09-20-p0-remediation-plan.md index 20082363..6ce9238e 100644 --- a/.doc/remediation/2026-09-20-p0-remediation-plan.md +++ b/.doc/remediation/2026-09-20-p0-remediation-plan.md @@ -1,6 +1,6 @@ --- title: "2026-09-20 P0 热修整改方案" -status: in_progress +status: done created: 2026-09-20 updated: 2026-09-20 --- @@ -31,12 +31,12 @@ updated: 2026-09-20 ## 验收标准 -- [ ] `curl :8080/health` → `schema_version=58`;`chat_summaries` 存在 -- [ ] 偏好跨用户写 / 他人 session 读 / 空 session 重分类 → 403 或 400 -- [ ] `go test -race` taskrun/chat/server short PASS;math XSS 单测 PASS -- [ ] backup 脚本无硬编码口令;push 不把 token 放 URL -- [ ] main health 恢复;旧口令无法登录 -- [ ] 测试报告归档;CURRENT 槽位 idle;不改 `production_ready` +- [x] `curl :8080/health` → `schema_version=58`;`chat_summaries` 存在 +- [x] 偏好跨用户写 / 他人 session 读 / 空 session 重分类 → 403 或 400 +- [x] `go test -race` taskrun/chat/server short PASS;math XSS 单测 PASS +- [x] backup 脚本无硬编码口令;push 不把 token 放 URL +- [x] main health 恢复;旧口令无法登录 +- [x] 测试报告归档;CURRENT 槽位 idle;不改 `production_ready` ## 非目标 diff --git a/.doc/remediation/gap-matrix.md b/.doc/remediation/gap-matrix.md index f0654a50..dd0f500a 100644 --- a/.doc/remediation/gap-matrix.md +++ b/.doc/remediation/gap-matrix.md @@ -94,3 +94,17 @@ ``` **结论**: 发布门禁四框已签。文档账本运行时 UI Round20 **PASS**;`CHAT-INTENT-STATE` 双标签 busy **PASS**;`DEMO-DB-SEED` **PASS**;BUG-08 **PASS**。`-race` TempDir flake 与 U9–U12 / 软件自举 / FAV / 完整 PI change-report 叙事不挡首发。不得把 fallback change report 写成完整 PI 叙事。 + +--- + +## 2026-09-20 P0 现场问题(同日收口) + +| ID | 描述 | 状态 | 证据 | +|---|---|---|---| +| P0-MIG | 00054 空洞 + chat_summaries 静默失败 | **PASS** | 重编号 `00058`;dev/main health schema=58;[报告](../test-reports/2026-09-20-p0-hotfixes-test-report.md) | +| P0-IDOR | 偏好写 / session 项目读 / 重分类越权 | **PASS** | 单元 + 真实 curl 403/400;同上报告 | +| P0-PANIC-RACE | taskrun closed-channel panic + 同步 chat 无锁 | **PASS** | 持锁 fanout;`WithExecLock`;`-race` Subscribe 测试 | +| P0-XSS | math 错误分支未转义 | **PASS** | BlockEditorModal/MathBlockView + escapeHtml 单测 | +| P0-CRED | backup 硬编码口令 + push URL token + 生产口令轮换 | **PASS** | 脚本无硬编码;docker 网旧口令 FATAL、新口令 OK;main health ok | + +> 不改 `production_ready`。main **git 分支**对齐仍为 backlog(T20-I7);环境库已随 rebuild 至 schema 58。 diff --git a/.doc/test-reports/2026-09-20-p0-hotfixes-test-report.md b/.doc/test-reports/2026-09-20-p0-hotfixes-test-report.md new file mode 100644 index 00000000..caac6921 --- /dev/null +++ b/.doc/test-reports/2026-09-20-p0-hotfixes-test-report.md @@ -0,0 +1,93 @@ +# 2026-09-20 P0 热修 测试报告 + +## 一、 测试背景 (Background) + +2026-09-20 系统全量体检发现多项 critical:迁移 00054 断链与 `chat_summaries` 静默失败、三项 IDOR、taskrun 向已关闭 channel 发送可致进程 panic、备份/推送脚本硬编码或暴露凭证、生产 DB 口令入库。P0 热修按 Wave 0–4 落地。 + +## 二、 测试目标 (Test Objectives) + +- 迁移链连续:dev/main schema=58,`chat_summaries` 存在 +- 三项 IDOR 负例 403/400 +- taskrun Subscribe/Unsubscribe 并发无 panic(`-race`) +- 备份脚本无硬编码口令;push 不把 token 放 URL +- main 库网络路径旧口令失败、新口令成功;main health ok + +## 三、 测试方案与环境 (Test Plan & Environment) + +- OS:linux;Go 1.27.1 +- 环境:dev `:8080`、test `:8081`、main `:8000`;真实容器(非 stub 冒充验收) +- 层级:单元/负例(`go test`、`-race`)、脚本静态检查、真实 curl / docker network psql + +## 四、 预期结果 (Expected Results) + +| 用例 | 预期 | +|------|------| +| health | schema_version=58(dev/main);chat_summaries 存在 | +| 偏好跨用户写 | 403 ERR_FORBIDDEN | +| 他人 session 读 projects | 403 SESSION_FORBIDDEN | +| 空 session 重分类 | 400 | +| 他人 session 重分类 | 403 | +| Subscribe race | PASS,无 panic | +| 旧生产口令(docker 网) | FATAL auth | +| 新生产口令(docker 网) | SELECT 1 | + +## 五、 实际测试结果与判定 (Actual Results & Evaluation) + +### 5.1 迁移与摘要表 + +- **输入**:`./scripts/env-service.sh dev rebuild`;capability 合入后 00054→00058 +- **实际输出**: + - `curl :8080/health` → `schema_version":58` + - `to_regclass('public.chat_summaries')` → `chat_summaries`;`max(version_id)=58` + - main rebuild 后亦为 `schema_version":58` +- **判定**:PASS +- **耗时**:dev rebuild ~41s;main rebuild ~48s + +### 5.2 三项 IDOR(单元 + 真实 curl) + +- **单元**:`TestUpdateUserPreference_CrossUserIs403` / `TestGetProject_OtherUserSessionDenied` / `TestChatRecategorize_RequiresOwnedSession` → `ok chat-agent-system/internal/server` +- **真实 curl(dev)**: + - `PREF_CROSS=403` `无权修改其他用户的偏好` + - `PROJ_CROSS=403` `无权访问该会话` + - `RECAT_EMPTY=400` `session_id is required` + - `RECAT_CROSS=403`(经 SQL 插入归属会话后)`SESSION_FORBIDDEN`;所有者 `RECAT_OWN=200` +- **判定**:PASS +- **耗时**:单元 ~1.6s;curl 秒级 + +### 5.3 进程稳定性 + +- **输入**:`go test -race ./internal/taskrun/ -run TestSubscribeUnsubscribeRace` +- **实际输出**:`ok chat-agent-system/internal/taskrun` +- **判定**:PASS(持锁 fanout + recover 兜底) +- **耗时**:~1.0s + +### 5.4 凭证与口令轮换 + +- **脚本**:`grep prod_highly|oauth2:${TOKEN}` → 两脚本命中数 **0** +- **main 网络认证**(scram,非 localhost trust): + - 旧硬编码口令:`NET_OLD_EXIT=2` FATAL + - 新口令:`NET_NEW_EXIT=0` → `1` +- **health**:`main` / events `:8090` status ok,schema 58 +- **判定**:PASS(口令内容不写入本报告) +- **耗时**:rebuild ~48s + +### 5.5 前端 XSS 转义 + +- **输入**:`npx tsx --test src/engine/replyDocument/replyDocument.test.ts` +- **实际输出**:`escapeHtml escapes math error payloads...` PASS +- **判定**:PASS + +## 六、 自动化测试套件汇总 (Test Suite Execution) + +``` +go test ./internal/server/ -run 'TestUpdateUserPreference_CrossUserIs403|TestGetProject_OtherUserSessionDenied|TestChatRecategorize_RequiresOwnedSession' → ok +go test -race ./internal/taskrun/ -run TestSubscribeUnsubscribeRace → ok +npx tsx --test src/engine/replyDocument/replyDocument.test.ts → 9 pass / 0 fail +``` + +全量 `go test -short ./...` 仍有已知外网镜像 flake:`TestPiAgentDockerBuildContext_RunnerModulesPresent`(docker.1ms.run EOF),记 long-term T20-I8,不挡本 P0。 + +## 七、 测试结论与后续优化建议 (Conclusion & Next Steps) + +- **结论**:P0 热修达到合入/冒烟标准;`production_ready` 保持 yes(无新增未关闭发布 blocker)。 +- **后续**:medium/low 见 [long-term 2026-09-20 增补](../ops/long-term/2026-09-19-audit-remainder.md);main **git 分支树**对齐晋升仍独立授权(环境 schema 已 58,分支仍落后);test 环境 schema 仍 57,下次晋升补 00058。