Skip to content

⚠️ 自动镜像 · 此页由 docs-site/scripts/mirror-changelog.mjsROADMAP/[archived]0.9.y.md 生成,请勿直接编辑此处;改源文件后 pnpm docs:build 会自动同步。

0.9.x 收尾三版规划(v0.9.13 / v0.9.14 / v0.9.15) ✅ ARCHIVED

已归档(2026-05-11):v0.9.13 / v0.9.14 / v0.9.15 全部落地,0.9.x 生命周期结束。下一阶段见 [archived]0.10.x.md

元计划。不是单版 plan,每版动手前再单独写 2026-mm-dd-vx.y.z-<codename>.md。 父引用:ROADMAP.md · [archived]0.10.x.md

Context

v0.9.12 (Humming Roaming Oasis) 收完 /ai-pre IA 重构 + B-14~B-17 BUG 反馈簇 + max_concurrency 限速后,0.9.x 主线(Grounded-SAM-2 接入)功能面已封口。下一步必须切到 v0.10.x SAM 3 接入大 epic。但 ROADMAP 里仍有一批 P2 / P3 条目悬空:v0.9.12 落地后新发现的小项、积累两版的 dev experience 痛点、以及一直被推迟的 P2 长尾(mask 多连通域、系统设置 admin UI、批次状态机二阶段、Bug LLM 聚类 + SMTP)。

目标:用 3 个收尾版本把 ROADMAP 优先级表里当前可现做且依赖就位的 P2 清零 + 把 v0.9.12 落地后 5 项新发现 + 积累的 dev experience 修复 + 测试 / 文档收口一并消化,让 v0.10.0 启动时 ROADMAP 「现在 open 的 P2」段只剩「等外部依赖」类(Bug LLM + SMTP digest 因 Anthropic 配额 / SMTP 测试链路未就位主动推迟,保留在 ROADMAP P2 段等条件成熟)。

节奏假设:每版 1-3 天,跟近期 v0.9.10→v0.9.12 节奏一致。每版独立 changelog + plan 文件,落完同步精简 ROADMAP。


版本切片

v0.9.13 — Eager Karp ✅(收尾 BUG 簇 + dev experience,2026-05-09 落地)

7/8 条收口(#8 用户已对齐推迟):① B-15 端到端 WS 链路实测全通(admin/anno 多端实时同步);② /ws/batches/project/{id} + BatchEventPublisher.publish_batch_status_change + useBatchEventsSocket (3 处接入:ProjectDetailPanel / BatchesSection / WorkbenchShell);③ ProjectDetailPanel 加 alias chips(点击 toggle + 一键重填)+ ThresholdRow(box/text slider + 显式保存);④ MlBackendFormModal 加 max_concurrency number input + RegisteredBackendsTab 行 chip;⑤ 3 个 WS hook smoke 测试(useGlobalPreannotationJobs / usePreannotation / useMLBackendStats,共 16 测试全绿);⑥ apps/api/app/main.py lifespan + ws.py:close_redis_pool() (asyncio.wait_for 2s timeout 兜底);⑦ apps/web/src/lib/wsHost.tsgetWsHost() / buildWsUrl(),4 处 hook 全迁移;⑧ 截图 fixture 推迟(不侵入 dev seed.py)。→ plan

v0.9.13 落地后新发现:① 实测一次 lifespan shutdown hang 后给 close_redis_poolasyncio.wait_for(timeout=2s) 兜底,避免 disconnect(inuse_connections=True) 等不到 task 取消时无限阻塞;② vite 上游 ws upgrade 卡死的 minimal repro issue 还没提(绕法保留,dev 直连 :8000 已抽进 helper),留 follow-up;③ 截图 fixture 4 张空白态需在 v0.9.14+ 与「单独 screenshot_fixture 路径」决策同步 — 确认是侵入 dev seed.py 还是新增独立脚本;④ 验证脚本里发现 rtk token-killer 代理会截断 curl stdout(>500 字节就丢), 后续大 JSON 测试要用 /usr/bin/curl 绕开。


v0.9.14 — Fluttering Wirth ✅(mask 多连通域 + 单测 + 文档,2026-05-09 落地)

3/4 主菜全收,#2 系统设置 admin UI 调研发现实际已落地(PATCH endpoint + SystemSection 编辑 UI + SMTP 测试按钮全齐),优先级表对应行删除,元计划 #2 改写为后续观察项。落地:① mask→polygon 多连通域 — mask_to_multi_polygon (RETR_CCOMP 抓内外环树) + PolygonGeometry.holes 默认 [] 向后兼容 + MultiPolygonGeometry discriminator + predictor 智能选择三种 LS shape 字面(单连通无 hole 字面与 v0.9.13 100% 一致)+ to_internal_shape 三 shape 解析 + 前端 transforms.geometryToShape 处理 multi_polygon 主外环降级 + 完整 polygons 透传 multiPolygon 字段(ImageStage Konva sceneFunc evenodd 镂空可视化推 v0.10.x 同窗口做)+ eval_simplify.py 双跑 single + multi(合成 fixture multi_only_helps 8.9%);② 前端单测 25→30 — 实测 30.30%, 425 case 全绿 (新增 GeneralSection 7 / DatasetsSection 7 / AuditPage 7 / BatchesSection smoke 3 / transforms 多连通 4 + 修 ProjectDetailPanel.test 缺 useUpdateProject + useBatchEventsSocket mock 致 worker crash 回归);③ ai-models.md §1 部署章节展开 (compose profile + nvidia 资源预留 + 显存预算表 + dev/生产差异);④ ADR-0013 加 v0.9.14 多连通域升级章节. → plan.

v0.9.14 落地后新发现:① 系统设置 admin UI 实际已落地(PATCH /settings/system RBAC SUPER_ADMIN + audit log + SystemSection 编辑 UI + SMTP 测试按钮全齐, apps/api/app/api/v1/system_settings.py:51-93 + apps/web/src/pages/Settings/SettingsPage.tsx:351-573), ROADMAP 优先级表对应行删除;② docker-compose 缺 mailpit / mailhog dev SMTP service, dev 测试 SMTP 链路要么挂外部 (MailTrap) 要么 v0.9.15 / chip:dev-experience 时加 mailpit;③ 前端 polygon 编辑器 PolygonTool 仍只支持单环, multi_polygon prediction accept 后转 annotation 取主外环(丢 hole / 其余 ring), 客户反馈触发再扩;④ ImageStage Konva sceneFunc + evenodd 镂空可视化与 v0.10.x sam3-backend 接入同窗口做(避免二次破窗);⑤ v0.9.13 落地遗留 ProjectDetailPanel.test.tsx 缺 useUpdateProject mock + useBatchEventsSocket mount 触发 ws upgrade 致 vitest worker libuv assert crash, v0.9.14 修复时一并 mock noop;⑥ vitest 在 RTK token-killer 代理下输出截断, 验证测试改用 /usr/bin/env CI=1 pnpm exec vitest run


v0.9.15 — Sorted Mountain ✅(批次状态机二阶段:admin-lock + bulk-approve/reject,2026-05-11 落地)

主题:清最后一个可现做的 P2 长尾(L),实施 ADR-0008。完成后 ROADMAP P2 段只剩「等外部依赖 / 客户驱动」类(Bug LLM + SMTP digest / 邮箱验证 / OAuth2 / 非 image-det 工作台 / OpenSeadragon / marquee 等), 立即开 v0.10.0 M0 sam3-backend。

Bug 反馈 LLM 聚类 + SMTP digest 不在本版:原计划与状态机一起做, 后调整为推迟 — Anthropic 配额 / SMTP 测试链路 / cluster UX 三项前置依赖未就位, 强行做风险高且无法在收尾版窗口里稳合。保留在 ROADMAP §B 可观测性段 + 优先级表 P2, 等三项任一就位(最可能:客户提需求触发 SMTP 链路验证)后单独立项, 与 v0.10.x 并行做。这意味着 v0.10.0 启动时 P2 段不为零, 但仅剩 "外部依赖未就位" 类条目, 跟用户已对齐

#条目动作要点引用
1scheduler 测试覆盖补齐(前置, 必须先做grep apps/api/tests/services/test_scheduler*.py 现有覆盖, 补 auto_transitions 完整状态矩阵:pre_annotated → annotating / annotating → review / review → completed / completed → archived 各种 in_progress task 数量边界。不补测试不动状态机实现(ADR-0008 caveat)ADR-0008
2批次状态机二阶段(实施 ADR-0008)Alembic 加 admin_locked bool / admin_locked_at / admin_locked_byscheduler.check_auto_transitions 短路 admin_locked batch 不让推回 annotating;in_progress task 同步复位 pending(释放标注员锁);REST /batches/{id}/admin-lock + /admin-unlockBatchesSection UI 加锁按钮 + 状态徽章 + 批量锁 / 解锁优先级表 P2,ADR-0008
3bulk-approve / bulk-rejectUX:reject 是逐批次反馈语义、bulk approve 跳过逐批次审视有质检失职风险;落地为 /batches/bulk-approve /batches/bulk-reject 仅 admin / super_admin 可调 + 审计日志强制写 reason 字段;UI 在 BatchesSection 多选菜单暴露 + confirm modal 二次确认ROADMAP §A 批次段

前置依赖(外部):仅 #1 测试覆盖(无外部资源依赖, 当天可补)。

关键文件

  • apps/api/tests/services/test_scheduler.py先扩, 补 ADR-0008 caveat 用例)
  • apps/api/app/db/models/task_batch.py + Alembic 新迁移
  • apps/api/app/services/scheduler.py + apps/api/app/services/batch.py:661+ check_auto_transitions(短路逻辑)
  • apps/api/app/api/v1/batch.py(admin-lock + bulk endpoints)
  • apps/web/src/pages/Projects/sections/BatchesSection.tsx(admin-lock UI + bulk action 菜单 + confirm modal)
  • docs/adr/0008-batch-admin-locked-status.md 状态从 Proposed → Accepted, 加「实施细节」章节

验证:① ADR-0008 用例矩阵全绿(admin_locked 阻断 scheduler / unlock 后正常推进 / bulk-approve 不绕过 admin-locked / in_progress task 复位释放锁);② 端到端:admin 锁批次 → 标注员页面看到禁用提示 → unlock 后正常进入;③ bulk reject 必填 reason 校验生效, 审计日志记录 reason;④ 测试覆盖率不掉(仍 ≥ 30%)。

v0.9.15 落地后新发现:① batch admin-lock 实施为 soft hold(不是 hard pause),locked batch 任务仍可见(GET /tasks 未过滤),当前够用;② bulk-approve/reject 权限收紧在 reviewer 级(非 owner-only),后端已实施,前端操作栏暂仅 owner 可见(实用够);③ TestAdminLock 测试跑 test_reporter_reopen_notifies_assignee 时在全套执行时有概率 "Event loop is closed" 失败(pre-existing flakiness,与本版改动无关,单独跑无问题);④ test_scheduler.py Phase 1 门控 19 cases 全绿,确认了新测试在「改动前」就能通过(正确基线),Phase 2 改动后仍保持全绿。→ plan.


风险与回滚

  • 批次状态机二阶段 scheduler 回归风险:ADR-0008 设计层面已稳, 但生产路径长(auto_transitions × admin_locked × bulk × in_progress task 复位)。先补测试再改实现的纪律不能省 — v0.9.15 #1 必做, 跳过 #1 直接做 #2 即放弃本版。
  • mask→polygon 协议 break:输出 type 从 polygon 升 multi_polygon,前端 Konva 渲染 + 老 prediction 历史读取需做 forward/backward compat 一段时间(discriminated union + 渲染层兼容 single polygon)。如发现历史 prediction 反序列化路径不止一处, v0.9.14 体量超时, 把前端单测 25→30 推到 v0.9.15 调整版次平衡。
  • vite 上游 issue 无响应:v0.9.13 #7 提 issue 后如长期无响应不阻塞收尾;helper 抽象本身价值独立。绕法保留到 v0.10.x 仍可接受。
  • Bug LLM + SMTP digest 推迟的连带影响:v0.6.9 已落 Bug 反馈通知 + 通知偏好基础静音, 但 cluster 折叠 / 邮件 digest 缺位意味着 BugReportListPage 数量上来后查找体验差。触发条件 = bug_reports 总条数 > 100 或 客户反馈邮件需求 → 单独立项, 写入 v0.10.x 并行 backlog(不在本元计划范围)。

收尾后立即触发

  • ROADMAP ## A · 代码观察到的硬占位 / ## B · 架构 & 治理向前演进 / 优先级表对应行删除已落项, 在每版 plan 后写 1 段「落地后新发现」(约定 #3 in §「优化建议 / 文档维护备忘」)
  • v0.9.x changelog 段(暂存 root CHANGELOG)整体迁回 docs/changelogs/0.9.x.md(开 v0.10 时该做)
  • 立即开 v0.10.0 plan:2026-mm-dd-v0.10.0-<codename>.md,参照 ROADMAP/[archived]0.10.x.md M0

不在本元计划范围

  • v0.10.x sam3-backend M0~M3(独立 epic, 已有 ROADMAP/[archived]0.10.x.md
  • Bug 反馈 LLM 聚类去重 + SMTP 邮件 digest(P2, 已对齐推迟):保留在 ROADMAP §B + 优先级表, 触发条件 = bug_reports > 100 或 客户提邮件 digest 需求;v0.10.x 并行做或独立小版本
  • 等独立 epic:非 image-det 工作台 / 大文件分片上传 / 数据集 snapshot / 2FA / OpenSeadragon 瓦片金字塔
  • 等业务规模触发:predictions 月分区 Stage 2 / batch_summary stored 列 / 审计冷数据归档物化
  • 等客户驱动:邮箱验证 / OAuth2 SSO(这两条 P2 但「触发条件 = 客户」与本元计划「P2 清零」无矛盾,本质是「触发后再做」的 P2,不算 open)
  • CSP style-src nonce 收紧(前置 = 全站 ~2600 处 inline style 重构, 与 v0.10.x ProjectSettingsPage 重构同窗口)

Released under the MIT License.