From 26d14b534b90467d76ad60ab666a7858ce47da10 Mon Sep 17 00:00:00 2001 From: weichen Date: Sat, 19 Sep 2026 13:22:38 +0000 Subject: [PATCH] docs(test): record schema 53 rebuild and login fanout on dev The rebuilt workbench issues one member request and one session list request. Slow-network samples improved, but twenty-run percentiles and the restart matrix are still open. Co-authored-by: Cursor --- .doc/ops/CURRENT.md | 8 +- .../long-term/2026-09-19-audit-remainder.md | 2 +- .doc/status/FEATURE-MATRIX.md | 2 +- .../deployed-8080-schema53.json | 306 ++++++++++++++++++ .../throttled-schema53.json | 38 +++ web/e2e/initial-load-performance.spec.ts | 2 +- 6 files changed, 351 insertions(+), 7 deletions(-) create mode 100644 .doc/test-reports/assets/2026-09-19-initial-load-u1/deployed-8080-schema53.json create mode 100644 .doc/test-reports/assets/2026-09-19-initial-load-u1/throttled-schema53.json diff --git a/.doc/ops/CURRENT.md b/.doc/ops/CURRENT.md index 411e2044..6d27bae9 100644 --- a/.doc/ops/CURRENT.md +++ b/.doc/ops/CURRENT.md @@ -1,11 +1,11 @@ # 当前焦点 **更新**: 2026-09-19 -**production_ready**: yes(门禁 B1–B4 已签;dev/test/main schema 52。不把 fallback change report 写成完整 PI) +**production_ready**: yes(门禁 B1–B4 已签;dev schema 53,test/main schema 52。不把 fallback change report 写成完整 PI) ## 焦点 -1. **2026-09-19 审计整改批 1–4 done**(合入 `844f757` / `08f4e0b` / `a2a49a6` / `d73bc79`)。余项见 [long-term](./long-term/2026-09-19-audit-remainder.md)。未晋升 test/main,未 rebuild 容器。 +1. **2026-09-19 审计整改批 1–4 done**(合入 `844f757` / `08f4e0b` / `a2a49a6` / `d73bc79`)。dev 已 rebuild 到 schema 53。余项见 [long-term](./long-term/2026-09-19-audit-remainder.md)。未晋升 test/main。 2. **Control Center 已移出本仓库**:项目进度由独立统一管理系统承担;本仓库恢复为智能体系统。见 [任务](./short-term/2026-09-19-remove-control-center.md) 3. **rdev 模板深度 / document-author-only**:已合入 `origin/dev`;未晋升 test/main 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 待合规签字 @@ -149,7 +149,7 @@ | holder | phase | since | scope | queue | |--------|-------|-------|-------|-------| -| - | idle | 2026-09-19 | 审计批 1–4 已合入 dev(844f757 / 08f4e0b / a2a49a6 / d73bc79);medium 见 long-term | - | +| Cursor-Auto | audit-remainder-closeout | smoke | 2026-09-19 | 二次 rebuild:恢复 00001/00012 校验和后的镜像 | - | **phase**: `idle` | `merging` | `smoke` | `e2e` @@ -159,7 +159,7 @@ | 环境 | 端口 | schema | 状态 | |------|------|--------|------| -| dev | 8080 | **52** | healthy(含 author_only goose 00050–00052;`pi-agent`;events `:8088`;**试点** `workflow.allow_author_only_approval=true`) | +| dev | 8080 | **53** | healthy(2026-09-19 `fix/audit-remainder-closeout` rebuild;goose `00053` `document_content_projections`;入口 `index-DOO0-Yh7.js`;`pi-agent`;events `:8088`) | | test | 8081 | **52** | healthy(Wave 2 rebuild 后 schema 与 dev/main 对齐;pi-agent `:18866`;events `:8089`) | | main | 8000 | **52** | healthy(`env=main` app+events 对齐;events 先 healthy 后启 app;consumer modes 全 off;Wave 1 已验证) | diff --git a/.doc/ops/long-term/2026-09-19-audit-remainder.md b/.doc/ops/long-term/2026-09-19-audit-remainder.md index 3b8fbaa2..083eca6d 100644 --- a/.doc/ops/long-term/2026-09-19-audit-remainder.md +++ b/.doc/ops/long-term/2026-09-19-audit-remainder.md @@ -49,7 +49,7 @@ updated: 2026-09-19 | FE App.tsx | 部分。登录壳不再静态引用重模块。本地缓存、登录同步、文档补水、服务端文档同步、生命周期、发送消息、块编辑、对话流/任务流重试、卡片动作、立项和成员写操作已分别抽出。工作台壳仍在 `App.tsx` | | H1-del | 关闭理由:`allowLegacyTestPrincipal` 仍被 `AllowInMemory && ContextDbHost==""` 的 dev/test 内存测试使用。删除会把这批测试变成未登录 401。保留告警,删除另开、先改测试夹具 | -仍开放:rdev P3 三样本真 PI、首次加载 U1 慢网/U6/U7、dev 容器重建与治理库 PG。公式引擎已离开入口包(`index-j0BIrjIR.js` 737.38 kB,br 170,451 B,包内无 katex),U3 在本仓 Vite 登录瀑布里未见 katex/mermaid/docx,但生产包瀑布要等重建后复测,不关。P4 键名空间化已在本分支落地:新清单用带前缀的任务键,旧键与旧 doc_id 仍可读,`TestPublishedTaskKeysAreNamespacedAndDisjoint`。意图短语仍输出旧键,执行路径按别名接上。P2 规划界面已折叠长阶段、可批量纳入人工审批,并在选中 rdev 时提示 CDO 前置。U4 源码收口在 Vite n=20 上成立(成员项目 1、会话列表 1);已部署 8080 旧包仍是 704/30,浏览器关账要等重建。2026-09-19 在 `fix/audit-remainder-closeout` 跑过 `cd web && npm test && npm run build`:node:test 414 pass / 0 fail,vitest 32 pass;入口 `index-BFf6n8IA.js` 1,005.01 kB,br 235,285 B。CURRENT 文首 schema 52 与三套容器一致,00053 要等重建后才升。H2 批注/审计的项目成员检查在 Postgres 上走 `RequireProjectAccess`;内存授权器在无库时把任意正用户 id 视为成员,这是 `TestAuthorizeDocRevision_ReviewerAndNonMemberCannotWrite` 的隔离前提,不能改成默认拒绝。H2 的 HTTP 负例因此要在 `TEST_DATABASE_URL` 上补,本机未设置该变量。M7 的投影意图已随账本提交(goose `00053`);容器 schema 仍是 52,要等占槽重建后才升到 53。 +仍开放:rdev P3 三样本真 PI、首次加载 U1 的 20 次分位数、U7 重启矩阵、工作台壳继续拆出 `App.tsx`。dev 容器已在 `fix/audit-remainder-closeout` 重建:goose 53,表 `document_content_projections` 存在,入口 `index-DOO0-Yh7.js`。U4 在该包上 n=5 为成员 1、会话列表 1。U3 首屏资源无 katex/mermaid/docx,匿名 JS 传输 172,417 B。U6 关闭理由:瓶颈是成员扇出,重建后已消失,没有对应慢 SQL,不加索引。H2 HTTP 负例:`TestDocGovCommentsAndAudit_NonMemberIs403_PG` 在隔离库 `127.0.0.1:5436` PASS。慢网 n=3 已低于拟定预算,但不足 20 次,U1 不关。test/main 仍是 schema 52,本轮不晋升。 红线关闭(不是实现): diff --git a/.doc/status/FEATURE-MATRIX.md b/.doc/status/FEATURE-MATRIX.md index 8c11aa8f..691d702a 100644 --- a/.doc/status/FEATURE-MATRIX.md +++ b/.doc/status/FEATURE-MATRIX.md @@ -96,7 +96,7 @@ ## 2026-09-17 首次加载性能专项 -首次加载与重启首访性能优化:**partial**(U2 静态交付已验收;U3 只做了登录壳拆包,未关闭)。[审计](../audit/2026-09-17-initial-load-performance-audit.md) · [方案](../remediation/2026-09-17-initial-load-performance-plan.md) · [U2 报告](../test-reports/2026-09-17-initial-load-perf-u2-test-report.md)。U2:自托管字体 + br/gzip。U3 进展(`fix/audit-remainder-closeout`):导出、预览、管理台、块编辑器、Mermaid/公式改为点击或出现时再加载。入口包 `index-*.js` 由 2.83 MB / br 626 KB 降到 737 kB / br 170 KB(`index-j0BIrjIR.js`,包内无 katex)。公式在气泡或正文里出现时才加载,富文本复制同样延后。U3 的浏览器资源瀑布还没测,本行不关。U5:`/auth/me` 复用本请求已核过的用户,不再第二次解析会话;会话与用户状态合成一次 JOIN。没有锁等待证据,所以不节流 `last_seen`。`TestAuthMe_LogoutNextRequestIs401`。U1、U6、U7 未做。U4 进展:登录不再按项目数拉成员名册,只同步当前项目;其他项目先种入当前用户以保持会话可见,完整名册在打开成员面板时取。会话列表不再因项目数组变化而重拉,迟到响应用代次丢弃,同一项目的在途成员请求合并。`src/data/initFanout.test.ts`。2026-09-19 浏览器证据(`e2e/initial-load-performance.spec.ts`,n=20,本仓 Vite `:3100` 代理 `:8080`):每次登录成员项目数 1、会话列表 GET 1,匿名与登录后资源路径均无 katex/mermaid/docx。同一探针打在已部署 `:8080`(旧包 `index-DhyNmxJE.js`,n=1)仍是成员项目 704、会话列表 GET 30,所以 U4 不能在容器重建前关掉。U1 本地登录态已有样本,10/2 Mbps 与 CPU 4 倍、U6、U7 仍未关。mutex `web + static-delivery`(U2 done)/ `loading-performance-audit`。 +首次加载与重启首访性能优化:**partial**(U2 静态交付已验收;U3 只做了登录壳拆包,未关闭)。[审计](../audit/2026-09-17-initial-load-performance-audit.md) · [方案](../remediation/2026-09-17-initial-load-performance-plan.md) · [U2 报告](../test-reports/2026-09-17-initial-load-perf-u2-test-report.md)。U2:自托管字体 + br/gzip。U3 进展(`fix/audit-remainder-closeout`):导出、预览、管理台、块编辑器、Mermaid/公式改为点击或出现时再加载。入口包 `index-*.js` 由 2.83 MB / br 626 KB 降到 737 kB / br 170 KB(`index-j0BIrjIR.js`,包内无 katex)。公式在气泡或正文里出现时才加载,富文本复制同样延后。U3 的浏览器资源瀑布还没测,本行不关。U5:`/auth/me` 复用本请求已核过的用户,不再第二次解析会话;会话与用户状态合成一次 JOIN。没有锁等待证据,所以不节流 `last_seen`。`TestAuthMe_LogoutNextRequestIs401`。U1、U6、U7 未做。U4 进展:登录不再按项目数拉成员名册,只同步当前项目;其他项目先种入当前用户以保持会话可见,完整名册在打开成员面板时取。会话列表不再因项目数组变化而重拉,迟到响应用代次丢弃,同一项目的在途成员请求合并。`src/data/initFanout.test.ts`。2026-09-19 浏览器证据(`e2e/initial-load-performance.spec.ts`,n=20,本仓 Vite `:3100` 代理 `:8080`):每次登录成员项目数 1、会话列表 GET 1,匿名与登录后资源路径均无 katex/mermaid/docx。同一探针在重建后的 `:8080`(`index-DOO0-Yh7.js`,schema 53,n=5)成员项目 1、会话列表 GET 1,匿名 JS 传输 172,417 B,首屏路径无 katex/mermaid/docx。重建前旧包 n=1 曾是 704/30。慢网 n=3、CPU 4 倍:10 Mbps 表单可见 558–604 ms,2 Mbps 1279–1296 ms,样本不足 20,U1 不关。U6 不加索引:测到的瓶颈是已消失的成员扇出,没有慢 SQL 证据。U7 重启矩阵未做。mutex `web + static-delivery`(U2 done)/ `loading-performance-audit`。 ## 2026-09-17 文档编制人兼任方案 diff --git a/.doc/test-reports/assets/2026-09-19-initial-load-u1/deployed-8080-schema53.json b/.doc/test-reports/assets/2026-09-19-initial-load-u1/deployed-8080-schema53.json new file mode 100644 index 00000000..2aee6dcb --- /dev/null +++ b/.doc/test-reports/assets/2026-09-19-initial-load-u1/deployed-8080-schema53.json @@ -0,0 +1,306 @@ +[ + { + "sample": 1, + "anonymousVisibleMs": 72, + "workbenchReadyMs": 131, + "anonymous": { + "navigation": [ + { + "ttfb": 1.7999999523162842, + "dcl": 33.60000002384186, + "load": 33.60000002384186 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 24 + }, + { + "name": "first-contentful-paint", + "ms": 72 + } + ], + "summary": { + "requestCount": 4, + "transferBytes": 223282, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "loggedIn": { + "navigation": [ + { + "ttfb": 1.7999999523162842, + "dcl": 33.60000002384186, + "load": 33.60000002384186 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 24 + }, + { + "name": "first-contentful-paint", + "ms": 72 + } + ], + "summary": { + "requestCount": 37, + "transferBytes": 816028, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "initRequests": { + "memberGetCount": 1, + "distinctMemberProjects": 1, + "sessionListGetCount": 1 + } + }, + { + "sample": 2, + "anonymousVisibleMs": 77, + "workbenchReadyMs": 132, + "anonymous": { + "navigation": [ + { + "ttfb": 2, + "dcl": 38.200000047683716, + "load": 38.200000047683716 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 24 + } + ], + "summary": { + "requestCount": 4, + "transferBytes": 223282, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "loggedIn": { + "navigation": [ + { + "ttfb": 2, + "dcl": 38.200000047683716, + "load": 38.200000047683716 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 24 + }, + { + "name": "first-contentful-paint", + "ms": 76 + } + ], + "summary": { + "requestCount": 37, + "transferBytes": 816028, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "initRequests": { + "memberGetCount": 1, + "distinctMemberProjects": 1, + "sessionListGetCount": 1 + } + }, + { + "sample": 3, + "anonymousVisibleMs": 85, + "workbenchReadyMs": 135, + "anonymous": { + "navigation": [ + { + "ttfb": 1.2000000476837158, + "dcl": 41.39999997615814, + "load": 42 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 44 + } + ], + "summary": { + "requestCount": 4, + "transferBytes": 223282, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "loggedIn": { + "navigation": [ + { + "ttfb": 1.2000000476837158, + "dcl": 41.39999997615814, + "load": 42 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 44 + }, + { + "name": "first-contentful-paint", + "ms": 88 + } + ], + "summary": { + "requestCount": 37, + "transferBytes": 816028, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "initRequests": { + "memberGetCount": 1, + "distinctMemberProjects": 1, + "sessionListGetCount": 1 + } + }, + { + "sample": 4, + "anonymousVisibleMs": 86, + "workbenchReadyMs": 128, + "anonymous": { + "navigation": [ + { + "ttfb": 1.2000000476837158, + "dcl": 42.200000047683716, + "load": 42.300000071525574 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 28 + } + ], + "summary": { + "requestCount": 4, + "transferBytes": 223282, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "loggedIn": { + "navigation": [ + { + "ttfb": 1.2000000476837158, + "dcl": 42.200000047683716, + "load": 42.300000071525574 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 28 + }, + { + "name": "first-contentful-paint", + "ms": 84 + } + ], + "summary": { + "requestCount": 37, + "transferBytes": 816028, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "initRequests": { + "memberGetCount": 1, + "distinctMemberProjects": 1, + "sessionListGetCount": 1 + } + }, + { + "sample": 5, + "anonymousVisibleMs": 89, + "workbenchReadyMs": 134, + "anonymous": { + "navigation": [ + { + "ttfb": 1.100000023841858, + "dcl": 41.200000047683716, + "load": 41.200000047683716 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 32 + } + ], + "summary": { + "requestCount": 4, + "transferBytes": 223282, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "loggedIn": { + "navigation": [ + { + "ttfb": 1.100000023841858, + "dcl": 41.200000047683716, + "load": 41.200000047683716 + } + ], + "paint": [ + { + "name": "first-paint", + "ms": 32 + }, + { + "name": "first-contentful-paint", + "ms": 88 + } + ], + "summary": { + "requestCount": 37, + "transferBytes": 816028, + "jsTransferBytes": 172417, + "jsCount": 1, + "heavyChunks": [] + }, + "longTaskCount": 0 + }, + "initRequests": { + "memberGetCount": 1, + "distinctMemberProjects": 1, + "sessionListGetCount": 1 + } + } +] \ No newline at end of file diff --git a/.doc/test-reports/assets/2026-09-19-initial-load-u1/throttled-schema53.json b/.doc/test-reports/assets/2026-09-19-initial-load-u1/throttled-schema53.json new file mode 100644 index 00000000..84977760 --- /dev/null +++ b/.doc/test-reports/assets/2026-09-19-initial-load-u1/throttled-schema53.json @@ -0,0 +1,38 @@ +[ + { + "profile": "10mbps-cpu4", + "sample": 1, + "anonymousVisibleMs": 604, + "workbenchReadyMs": 345 + }, + { + "profile": "10mbps-cpu4", + "sample": 2, + "anonymousVisibleMs": 575, + "workbenchReadyMs": 351 + }, + { + "profile": "10mbps-cpu4", + "sample": 3, + "anonymousVisibleMs": 558, + "workbenchReadyMs": 338 + }, + { + "profile": "2mbps-cpu4", + "sample": 1, + "anonymousVisibleMs": 1279, + "workbenchReadyMs": 361 + }, + { + "profile": "2mbps-cpu4", + "sample": 2, + "anonymousVisibleMs": 1296, + "workbenchReadyMs": 338 + }, + { + "profile": "2mbps-cpu4", + "sample": 3, + "anonymousVisibleMs": 1284, + "workbenchReadyMs": 345 + } +] \ No newline at end of file diff --git a/web/e2e/initial-load-performance.spec.ts b/web/e2e/initial-load-performance.spec.ts index 6e3060e4..111cdd40 100644 --- a/web/e2e/initial-load-performance.spec.ts +++ b/web/e2e/initial-load-performance.spec.ts @@ -185,7 +185,7 @@ test('throttled login still reaches the workbench', async ({ browser }) => { const anonymousVisibleMs = await openAnonymous(page); const workbenchReadyMs = await login(page); rows.push({ profile: profile.name, sample, anonymousVisibleMs, workbenchReadyMs }); - writeFileSync(path.join(evidenceDir, 'throttled.json'), JSON.stringify(rows, null, 2)); + writeFileSync(path.join(evidenceDir, process.env.INITIAL_LOAD_THROTTLE_EVIDENCE || 'throttled.json'), JSON.stringify(rows, null, 2)); await context.close(); } }