bed4d734ca4ab489ed4c45d63eb6690d0d248b3d
苍梧疑冢 · 互动剧情测评(MVP)
陌生人交友匹配 app 的冷启动载体:单人互动叙事("影游")。MVP 范围 = 影游第一幕(3 章)
- 人格画像报告 + 勋章分享卡,不含匹配和聊天。
产品共识见 CONTEXT.md,架构决策见 docs/adr/0001~0004,剧本母本见
docs/story-framework.md(第 4 节是 Act 1 全部选择点地图)。
怎么跑
pnpm install
pnpm dev # 浏览器开发(无 API key 时自动降级 Mock,见下)
pnpm build # 类型检查 + 产物构建
pnpm verify # 无头校验:选择点地图对照母本 + 引擎三章流程 + 重玩语义(Mock)
pnpm verify:live # 真 key 冒烟:C1-01 抽取 + C1-02 情绪签名 + 7 维 score(读 .env)
pnpm lint # oxlint
pnpm tauri dev # Tauri 桌面壳(Rust 工具链需先 source ~/.cargo/env)
Jev(TypeSafe AI System One)配置
复制 .env.example 为 .env,填入 key:
VITE_TYPESAFE_API_KEY=<your key>
- 有 key:前端直连
POST https://api.typesafe.ai/v1/systemone(HttpJevClient)。 - 无 key:自动降级
MockJevClient(确定性伪随机返分,console 有提示),开发联调不受影响。 .env已在.gitignore中,绝不能入库;scripts/verify-live.ts手动解析.env(不引 dotenv),任何输出都不打印 key。- 请求/响应 schema 已按真接口 curl 实测对齐(2026-10-03):Question 文本字段为
instructions;choice 的criteria是{选项: 描述}map;score 的criteria为 2-10 级有序数组(索引 0 起),答案是概率加权浮点值 +legend+probabilities。
项目结构
content/chapters/ Act 1 三章剧情数据(JSON,选择点 ID/维度标签对母本第 4 节)
src/engine/ 数据驱动剧情引擎(纯 TS,与 UI 解耦)
types.ts 章节 schema:dialogue / choice / narration / cutscene / identity / chapterEnd
engine.ts StoryEngine 状态机:节点推进、分支、情绪签名→场景变体、
身份抽取(extractIdentity)与确认(confirmIdentity)、重玩
eventStore.ts EventStore 接口(append-only,只有 append/list)+ localStorage 实现
src/services/jev.ts JevClient 接口 + HttpJevClient / MockJevClient
src/ui/ 最简影游界面(对话框/选项/VoiceInput 语音输入/身份登记/场景变体渐变)
src/ui/report/ 画像报告(Jev 7 维 score)、勋章映射、canvas 分享卡
scripts/verify.ts 内容完整性与流程校验(Mock 回归)
scripts/verify-live.ts 真 key 冒烟
src-tauri/ Tauri 2 壳(iOS/Android/桌面共用)
架构要点
- append-only 事件存储(ADR-0004):
EventStore类型层面只有append/list, 没有 update/delete 路径。重玩 = 新 sessionId 的新轨迹,旧事件原样保留。 - 三通道边界(ADR-0003):主线全部预写在 JSON 里;Jev 在讲述点只做
"情绪签名 → 预写场景变体" 的选择题(通道 1);C3-02 问心幻境通过
variantFrom: "C1-02"复用第一章的记忆解析。 - 语音输入:
VoiceInput组件优先用 Web Speech API(zh-CN,continuous + interimResults,实时转写),不支持的环境(如 Tauri WKWebView)优雅降级为文本框。 只保留转写文本、不保存任何音频,天然符合 ADR-0004"特征提取后即焚"。 - C1-01 语音化身份登记:馆长邀请自由介绍(称呼/年龄/城市/职业/学历),
Jev 一次调用并行抽取:gender(choice)、age(score 分档)、occupation(choice)、
education(choice)、city(noul 判断是否提及 + 城市 choice 兜底);
抽不出的字段留空,进确认页由用户修改补填,确认后 append
profile事件 (身份字段是匹配硬过滤字段,用户有权直接改,不进行为信号流)。 - 画像报告:Act 1 结束后把全部行为轨迹(不含 profile 字段)汇总为 state, 一次 Jev 调用并行问 7 个维度的 score 问题(10 级 criteria),API 返回的 0-9 浮点分数 +1 映射为 1-10 级展示;勋章取置信度最高的维度。
已知缺口
- CORS:浏览器直连
api.typesafe.ai可能有跨域限制,正式环境需加后端代理转发。 - Web Speech API 覆盖:Chrome/Edge 可用,Tauri WKWebView 与 Firefox 不支持 (自动降级文本框);原生端的正式 ASR 管线未接。
- Tauri SQLite 未实现:
EventStore目前只有 localStorage 实现;原生端应用 tauri-plugin-sql 实现同一接口(表只建 INSERT/SELECT,不建 UPDATE/DELETE 路径), 预留位置见src/engine/eventStore.ts末尾注释。 - Tauri 移动端(iOS/Android)推送与构建未验证:目前只验证了 Rust 壳
cargo check与tauri info,未跑tauri android/ios build。 - 追问补全未接:讲述点 schema 里有
followUp策略占位(Jev 缺失维度检测 + NPC 口吻追问,至多 1-2 句),MVP 未实现。 - 美术全部占位:CSS 色块 + 渐变,无图片/视频素材;cutscene 节点是占位渲染。
- 自适应支线路由未实现:story-framework 第 6 节的低置信度维度插支线属于后续章节工作。
Languages
TypeScript
96.3%
CSS
3.4%
Rust
0.2%
HTML
0.1%