What to build: 把前三票的「方案通过」收成「生产可用」:确认矩形内部换级与各降级路径的真实表现,拿到性能与走查证据,回写偏差,并把可丢弃原型归档。
Blocked by: 39
Status: claimed Labels: ready-for-agent
cockpit-primary-area-guardrails/spec.md、spec-fog.md。cockpit-primary-area-guardrails/issues/07-fog-implementation-spec.md、08-coarse-to-fine-transition-solution.md(均已 resolved)。cockpit-primary-area-guardrails/map.md 的「Not yet specified」两条。spec.md / spec-fog.md 的偏差逐条回写票面;改口径需维护者确认,不静默漂移。/cockpit 入口的 DEV 接线单独保存到 throwaway 分支,并在本票留分支指针;/cockpit 的 pages 入口在生产路径下不再挂原型。docs/cockpit-deployment.md 增一节「限位与雾气是否生效」(或明确记为遗留,写明原因)。原话:
退出到地球视图后,在重新回到引导状态时,摄像机角度没有回到引导状态,且地球也没有重新开始旋转, 除了中心出现「点击进入系统」外用户不一定能意识到进入引导状态了。
这不是新需求,是一次实现漂移 —— ADR 0009 第 27 行早已写死: 「全球态闲置 5 秒未操作 → 回到程序初始态:地球自转恢复 + 屏幕中央闪烁『点击进入系统』」。 所以它同时踩了两条既有契约:票 37 验收第 3 条、以及上面这句 ADR。
两个根因(都在代码里坐实,不是猜):
CockpitShell.vue 的 returnToIntro() 只做了两件事 ——
introVisible.value = true 与 setGlobeSpin(...),没有把相机送回去。
于是画面停在用户最后停留的视角上,"回初始态"就只剩中央那行字。mapService 用了粘滞开关 instance.spinPaused:
goHome() 与 returnGlobal 把它置 true,而 setGlobeSpin(>0) 命中它时 return true ——
代码里没有任何地方会把它清回 false。于是回引导态那次起转被静默吞掉,
且调用方(外壳挂载时的 600 ms 重试)以为已经成功、不再重试。修法:
mapService.resetToIntroView(),把相机送回 INITIAL_PANORAMA(0/−60/2×10⁷),
中心沿用当前位置(与「返回全球」同一条口径);returnToIntro() 改成
「显示引导层 + 回初始全景 + 恢复自转」三件事一起做。
已经在初始全景上就不排飞行 —— 否则自转要白等一个飞行时长才起得来。spinWanted(想要几秒一圈)、循环 instance.spin。
setGlobeSpin() 先记意图;"现在能不能转"按相机是否真的停稳(state.settled)判,
不能转就如实 return false(不再假装成功);等相机落定后由 resumeSpinIfWanted() 自动接上
(挂在 notifyCameraStateChange,飞行最后一帧必到)。
stopSpin() 负责放弃意图(进入系统/归位/返回全球都不该再自己转起来),
startSpin() 只停循环、不抹掉意图。spinWanted:只报 spin 分不清「意图立着但相机还没落定」与「压根没想转」。证据:
verify/t40-intro-return.mjs(静态守卫 + 一处纯行为断言):禁止 spinPaused 复活、
断言"记下意图之后不得 return true"、断言 stopSpin 放弃意图而 startSpin 只停循环、
断言落定后兑现意图、断言 returnToIntro 三件事齐备、断言 resetToIntroView 套用初始全景
且已在其中时不排飞行、断言阈值复用 SETTLE_EPSILON、断言读数带 spinWanted。return true 假装成功、spinPaused 复活、startSpin 误用 stopSpin、stopSpin 不放弃意图、
落定后不兑现、回引导态不送相机、不套用初始全景、去掉"已在其中"短路、改用魔数、读数去掉 spinWanted。data-fog-phase → data-map-fog-phase;实际写的是 host.dataset.mapFogPhase)。t04-config 与本票无关(并发会话的 cockpitApi.js
硬编码后端地址,见票 07 方向);t37 已随「契约改 10 秒」转绿。domain/areaLimits.js 的实现值原先是 10000;本轮并发写入期间一度被改成 2000,导致 t37 立即失败。维护者已经明确选择「我要 10 秒:把契约一起改」,因此我把实现恢复为 10000,并同步更新了五处权威:
ADR 0009 / 票 37 验收 / 部署手册 / 常量注释 / 闸门 t37(含 walkthrough 的等待时长)。
现在实现与契约重新一致,t37 已转绿。
| # | 验收项 | 状态 |
|---|---|---|
| 1 | 矩形内部 LOD 换级真机确认;可辨则在不接管场景/不引第二渲染器边界内评估 | 遗留 —— 观感判据,需真机(本会话工具清单里没有浏览器工具) |
| 2 | 异常降级四条路径各有可复现证据且提示如实 | 部分 —— 逻辑面已覆盖(① 无深度能力 / ② 自建雾失败 → t38-fog;③ 目标瓦片失败 → t39-handover;④ 主场景区未配置 → t36/t37);真机逐条复现仍缺 |
| 3 | 管线视图:近处管线可读;若因透明深度错位减弱/暂关雾,记录处置与文案 | 遗留 —— 需真机 |
| 4 | 性能:无原型基线与开雾后 P95 帧耗时,合计增幅 ≤15%;首启与进出切换卡顿单独记录 | 遗留 —— 需真机同机/同分辨率/同视角采样。(票 38 曾测得开/关雾 P95 增幅 0%,但那是 CPU 侧口径、且不是本票要求的"无原型基线",不能顶替) |
| 5 | 走查证据:进入 → 锁定 → 拉远被夹 → 边界回弹 → 返回全球 → 闲置回引导;覆盖浅俯角与多旋转方向 | 部分 —— 末段「闲置回引导」的功能缺陷本轮已修并有闸门+变异;链路其余段由 t37-area-limits-walkthrough 脚本覆盖。真机逐帧观感与"多方向"仍待维护者 |
| 6 | 规格同步:实现与 spec 的偏差逐条回写;改口径需确认 | 部分(已回写两处,均经维护者确认或记录) —— ① 票 39 的部署值 vs 代码默认(有意分离,已记录);② GLOBAL_IDLE_MS 5秒→10秒(维护者 2026-09-30 确认,契约五处已同步,见上) |
| 7 | 原型归档到 throwaway 分支 + 留分支指针 + 生产路径不挂原型 | 已完成(2026-09-30,维护者确认"现在就做") —— 归档分支 throwaway/cockpit-prototypes @ 81932a0;生产树已删 src/modules/cockpit/prototypes/ 并摘除 /cockpit 入口接线(见下) |
| 8 | 运维自检:手册增一节「限位与雾气是否生效」 | 已完成 —— 手册第 5 节「部署后自检」已含主场景区/进区限位/区内视距雾/雾的高度收口/雾不"一瞬间"散掉/粗→精交接/先收后撤全表;本轮补「闲置回引导」一行并修一处属性名错误 |
| 9 | 收口时区分已验证 / 已知代价 / 遗留 | 进行中 —— 见上表与下方"已知代价" |
requireTilesLoaded: false 牺牲的正是决策 08 设它要防的"先空白再跳方块"(票 39 记录)。归档用 git plumbing(临时 index)完成,没有动工作树里的并发在途改动:
throwaway/cockpit-prototypes @ 81932a0
(git log -1 该分支查看 commit:'归档:可丢弃原型(Transition/Fog/Anchor)与 /cockpit DEV 接线(票 40 收口)')src/pages/cockpit/index.vue):
anchor-prototype-effects.js、anchor-prototype-layout.js、AnchorPrototype.vue、
fog-prototype-stage.js、FogPrototype.vue、transition-prototype-scene.js、TransitionPrototype.vuesrc/modules/cockpit/prototypes/;src/pages/cockpit/index.vue 已摘除
三组 defineAsyncComponent / show*Prototype 接线(现在只挂 CockpitShell,全仓再无 cockpit/prototypes 引用)。t39-handover.mjs 原先读 TransitionPrototype.vue 的两条断言改为
断言"生产树已无 prototypes/ 目录";服务层的 alpha 互斥开关(setHandoverPrototypeActive /
applyHandoverAlpha 内 if (handoverPrototypeActive) return)保留 —— 一旦日后从归档分支还原原型,
互斥仍成立。cesiumEngine.js 两处提到 prototypes/fog-prototype-stage.js 的注释已标注"已归档分支"。git checkout throwaway/cockpit-prototypes -- src/modules/cockpit/prototypes src/pages/cockpit/index.vue0/−60/2×10⁷ + 星球重新自转);按手册第 5 节「闲置回引导」自检行
读 __cockpitMap.getLifecycleStats() 的 spin/spinWanted 与 getCameraState() 即可。