110 lines
4.4 KiB
Markdown
110 lines
4.4 KiB
Markdown
# M1/M2 第三并行波次状态
|
||
|
||
日期:2026-07-28
|
||
|
||
集成分支:`integration/v1`
|
||
|
||
起始基线:`4157f87`
|
||
|
||
## 本波次目标
|
||
|
||
- 在 Rust 1.96 下关闭此前未执行的核心编译、测试与 Clippy 门;
|
||
- 将动态演出完整保存到故事节点,并从节点恢复同一 `PlayerView`;
|
||
- 为 SQLite 建立可辨认、可拒绝损坏状态的 schema 生命周期;
|
||
- 实现真实 `lapp-rs` 非流式 TurnPlan provider;
|
||
- 保持模型、状态提交和玩家视图之间的安全边界。
|
||
|
||
开发继续使用 1 个集成人和 3 个独立 worktree。三个工作面分别负责
|
||
Presentation、Store Hardening 和 LAPP Provider;游戏运行时仍是单模型架构。
|
||
|
||
## 已集成
|
||
|
||
### 可恢复的演出快照
|
||
|
||
`StoryNode` 现在持久化一份 `PresentationSnapshot`:
|
||
|
||
- scene id 与公开标题;
|
||
- 主角色 id、名称、最终 expression 与 pose;
|
||
- 本轮演出 beats;
|
||
- 可编辑行动 suggestions;
|
||
- `canContinue`。
|
||
|
||
`TurnPlan` 只提交内部演出快照和 `StateDelta`,最终 `PlayerView` 仍由可信投影器
|
||
在事务提交后生成。旧的 beats-only 节点可通过默认值反序列化;重启恢复会保留
|
||
表情、姿态、节拍和建议,不再依赖运行时重新生成。
|
||
|
||
前端已消费 `characterExpression` 与 `characterPose`,浏览器确定性 adapter 也会
|
||
按本轮最后一个视觉指令更新角色状态。
|
||
|
||
### SQLite schema 生命周期
|
||
|
||
- 新数据库初始化为 schema v1,并通过 `PRAGMA user_version` 标记。
|
||
- 完整的旧版无版本数据库会在事务内采用为 v1,不丢失节点、状态或分支头。
|
||
- 不完整的 v0、损坏的 v1 和未来版本都会被拒绝,不会静默重建。
|
||
- 文件数据库启用 WAL、5 秒 busy timeout、foreign keys 与 synchronous NORMAL。
|
||
- 写入、恢复、结构列和 `state_hash` 的交叉校验继续保留。
|
||
|
||
### LAPP TurnPlan provider
|
||
|
||
- 使用固定的相邻 `lapp-rs`,启用 Rustls 客户端与系统凭据库。
|
||
- 非流式 chat 在独立 Tokio worker 中运行。
|
||
- 接受一个指定工具调用或裸 JSON,两者都经过相同严格结构校验。
|
||
- 模型只能返回 scene、character、beats、delta、suggestions 与 canContinue。
|
||
- `PlayerView`、`committedNodeId`、未知字段、歧义工具调用和无效标识符都会被拒绝。
|
||
- 提交节点 ID 由 story、branch 与 action 的稳定哈希产生,不能由模型伪造。
|
||
- 上游错误与无效输出经过脱敏,不回显 provider 原文或凭据。
|
||
|
||
真实 provider 暂不作为 Tauri 默认实现。下一步必须先建立上下文编译器和由引擎
|
||
掌控的类型化隐藏检定工具循环,避免模型直接提出未经裁决的判定记录或跨过
|
||
“一轮只提交一次”的原子边界。
|
||
|
||
### 桌面接线
|
||
|
||
- Tauri 从已提交节点恢复完整演出快照。
|
||
- “许诺 → 提交 → 恢复”测试增加 beats、suggestions、expression 与 pose 一致性。
|
||
- 补齐应用 SVG 源图标和 512×512 RGBA PNG,Tauri 宏可完整展开。
|
||
- `Cargo.lock` 首次纳入版本控制,固定 Rust 依赖解析结果。
|
||
|
||
## 已通过验证
|
||
|
||
```text
|
||
Rust 1.96.0
|
||
|
||
cargo fmt --all -- --check
|
||
|
||
cargo test -p nana-domain -p nana-engine -p nana-runtime -p nana-store -p nana-contracts
|
||
67 tests passed
|
||
|
||
cargo clippy -p nana-domain -p nana-engine -p nana-runtime -p nana-store \
|
||
-p nana-contracts --all-targets -- -D warnings
|
||
|
||
cargo check -p nana-story-app --all-targets
|
||
cargo clippy -p nana-story-app --all-targets -- -D warnings
|
||
Tauri lib、binary 与 6 个 test target 类型检查通过
|
||
|
||
node scripts/verify-contracts.mjs
|
||
16 schemas and TypeScript DTO source hash verified
|
||
|
||
vue-tsc --noEmit
|
||
|
||
vitest run
|
||
4 test files passed
|
||
12 tests passed
|
||
|
||
vite build
|
||
production build succeeded
|
||
```
|
||
|
||
当前 Linux Work 环境没有 WebKitGTK、Rsvg 与完整桌面链接依赖。Tauri 检查使用
|
||
本地 compile-only pkg-config shim 完成 Rust、宏和测试 target 的类型检查,
|
||
不等价于实际链接或窗口启动。真实 `pnpm tauri dev` 和 Windows 打包仍需在具备
|
||
原生依赖的环境验证。
|
||
|
||
## 下一波次
|
||
|
||
1. 建立确定性的上下文编译器,按预算选择角色卡、世界书、Persona、剧情与状态。
|
||
2. 建立类型化工具循环,由引擎执行隐藏 CoC7 判定和受控状态操作。
|
||
3. 将 LAPP provider 接入该工具循环,并保持整轮只有一次 SQLite 提交。
|
||
4. 为回溯面板接入“从这里继续”,创建新分支且保留旧分支头。
|
||
5. 在 Windows CI 或本机完成 Tauri 启动、重启恢复和安装包冒烟。
|