第15章 学生项目冲刺三:发布v0.1

本周目标只有一个:让项目第一次从真实物理输入走到用户可见结果,并用v0.1标签固定下来。模型尚未完成时,使用经过说明的基线判断;服务器尚非产品必要组成时,先完成本地反馈。不能为了保持原架构而等待所有组件成熟。

真实物理输入
→ 可验证判断
→ 产品事件
→ 用户反馈
→ 版本与证据

v0.1是第一个能够运行和失败的产品版本。它使团队从“讨论接口”进入“依据实际系统修改接口”。

集中到期末再合并各组件,容易同时出现多项故障,难以判断原因。小步合并把一次变化限制在较小范围内,并让主分支持续接受检查。它增加了评审次数,却降低了单次集成和回退的难度。

完成本章后,应当能够:

15.1 冻结本周范围

周初从v0.1里程碑选出必须项:

[ ] 一个输入适配器
[ ] 一个基线判断
[ ] 一个产品事件
[ ] 一种用户反馈
[ ] 一条失败处理
[ ] 构建和最小测试
[ ] 真实设备验证
[ ] README.md和发布记录

本周不新增:

新想法建立议题并放入v1.1候选,不进入当前冲刺。

15.2 选择最短闭环

不同项目可以选择:

本地反馈闭环

传感器/按键
→ 基线判断
→ 事件策略
→ 指示灯、声音或本地显示

适合不需要远程查看的项目。

端云反馈闭环

传感器/按键
→ 基线判断
→ 事件
→ 服务器确认
→ 授权页面

适合需要记录、远程反馈或多次查询的项目。

网关反馈闭环

传感设备
→ 串口或局域连接
→ 课程网关
→ 服务器或用户端

适合设备尚不具备直接网络能力的项目。网关是正式架构组件,必须记录其版本和失败行为。

选择依据是用户结果和当前硬件,不是系统组件数量。

15.3 先合并事件契约

正式实现前确认:

event_type含义
event_id生成位置
设备和事件时间
版本字段
判断证据
错误状态
数据模式版本

一个脱敏示例通过自动检查后,先合并契约合并请求。设备、服务器和用户反馈分支从该提交建立。

如果一周内契约仍频繁变化,说明团队没有确定核心结果。只保留v0.1必填字段,把扩展字段推迟。

15.4 实现真实输入适配器

输入接口最少提供:

enum class InputStatus {
  kOk,
  kNotReady,
  kDeviceError,
  kDataInvalid
};

class InputSource {
 public:
  virtual InputStatus begin() = 0;
  virtual InputStatus read(InputFrame& frame) = 0;
  virtual ~InputSource() = default;
};

InputFrame根据项目定义时间、通道、单位和状态。

真实设备验证:

[ ] 设备身份和硬件修订正确
[ ] 初始化成功或给出明确错误
[ ] 正例输入可观察
[ ] 反例不被输入层改写成正例
[ ] 时间和序号可解释
[ ] 连续运行没有静默溢出

若正式传感器仍不稳定,可用板载按键建立端到端路径。本周仍要保留一次目标传感器的真实读取证据。替换任务应列为第16章的阻塞议题。

15.5 建立可替换的基线判断

基线判断可以是:

它必须满足:

输入和输出接口与正式模型一致
结果可重复
规则和参数有版本
限制写入README.md
不会被表述为最终AI能力

示意:

struct DecisionResult {
  bool valid;
  bool target_detected;
  float score;
  const char* decision_version;
};

class DecisionEngine {
 public:
  virtual DecisionResult evaluate(const InputFrame& frame) = 0;
  virtual ~DecisionEngine() = default;
};

第16章的ModelRunner实现同一输出语义,上层事件和反馈无需重写。

15.6 完成用户反馈

用户反馈至少回答:

本地反馈不能只用调试串口代替。串口是工程证据,指示灯、显示、提示音或批准的用户页面才是产品结果。

端云项目核对同一event_id:

设备日志
→ 网络响应
→ 服务器记录
→ 用户页面

本地项目核对同一事件序号:

输入日志
→ 决策日志
→ 输出状态

15.7 让AI按议题推进代码

每个任务先在规划模式中提交:

目标:实现议题#<编号>的一个组件。

读取:
- 议题和验收条件
- 已合并的接口
- 当前组件文件
- 对应测试

禁止:
- 改变产品范围和事件契约
- 修改其他成员组件
- 添加未批准依赖
- 使用真实秘密
- 自动提交、推送和合并

输出:
1. 当前接口理解;
2. 最小修改步骤;
3. 每步文件范围;
4. 验证命令;
5. 可能的接口风险。

计划通过后才实施。每完成一步执行:

git status --short
git diff --stat
git diff

代码能编译后仍需学生检查:

15.8 小步合并而不是周末集中合并

推荐合并顺序:

契约
→ 项目骨架和统一命令
→ 输入适配器
→ 基线判断
→ 反馈组件
→ 集成

一个合并请求满足验收即评审合并。长期分支会同时积累接口偏差、冲突和不可验证变化。

每次合并后,其他分支同步:

git fetch origin
git switch <任务分支>
git merge origin/main

课程初期优先使用合并保留清楚历史。若团队采用变基,必须理解它会重写未共享提交,并遵守教师规定。

15.9 处理接口冲突

出现冲突时:

  1. 阅读两个议题;
  2. 确认已合并的契约版本;
  3. 判断哪一侧包含最近一次批准的接口;
  4. 形成满足当前v0.1的最终代码;
  5. 重新运行双方测试;
  6. 在合并请求说明解决方法。

不要让AI只看到冲突文件。它还需要议题、契约和当前main,人工决定最终行为。

若两个分支分别增加了不同字段,先判断字段是否属于v0.1。非必要字段删除或推迟,不直接合并两套结构。

15.10 持续查看进度和阻塞

每天结束时更新:

| 必须议题 | 状态 | 阻塞 | 下一证据 | 负责人 |
|---|---|---|---|---|

一个议题阻塞超过半天时:

  1. 写出当前版本、命令和第一条错误;
  2. 判断是需求、接口、硬件、模型还是环境;
  3. 请求对应课程成员协助;
  4. 启用已批准降级方案;
  5. 不同时开启多个替代实现。

本周进度优先级:

端到端闭环
> 核心失败处理
> 可重复构建
> 附加功能和界面完善

15.11 执行v0.1验证

15.11.1 自动检查

python tools/project.py doctor
python tools/project.py build
python tools/project.py test

按项目增加:

15.11.2 实机成功路径

记录:

- 硬件修订:
- 固件提交:
- 规则/模型版本:
- 契约版本:
- 操作:
- 输入实际结果:
- 决策实际结果:
- 事件ID或序号:
- 用户反馈:
- 延迟或其他指标:
- 证据路径:

15.11.3 至少一条失败路径

按项目选择:

系统不得把失败显示为成功,错误应能定位到组件。

15.12 发布v0.1

更新README.md:

当前能够运行什么
支持的硬件
快速验证步骤
基线判断是什么
正式模型尚未完成什么
成功和失败路径
当前限制

更新需求追踪、物料清单、CHANGELOG.md和验证记录。发布检查:

[ ] 真实物理输入进入系统
[ ] 用户看到可理解结果
[ ] 基线判断与正式模型接口可替换
[ ] 自动检查通过
[ ] 成功路径实机通过
[ ] 至少一条失败路径实机通过
[ ] 每个构建物可追溯Git提交
[ ] README.md没有夸大当前能力
[ ] 没有秘密和未授权数据
[ ] 所有v0.1阻塞议题关闭

创建:

git switch main
git pull --ff-only
git tag -a v0.1.0 -m "v0.1.0 first physical product loop"
git push origin v0.1.0

15.13 本章小结

本章完成学生项目的第一个真实版本。团队稳定事件契约,把输入、判断和反馈拆成可替换组件。小步合并请求保持持续集成,真实设备用于验证成功和失败路径。

v0.1使第16章的数据与模型工作有了明确产品接口。模型接入的任务不是重新开发整个系统,而是替换基线判断并保持事件和用户反馈链路稳定。

15.14 综合实践

  1. 画出本组最短产品闭环,删除一个不影响用户结果的组件,并说明删除后的边界。
  2. 选择一个议题,让AI在限定文件中实施。保存计划、Git差异、人工修正、测试和合并请求证据。
  3. 设计并实现一条明确失败路径。系统不得把失败记录为成功,用户或开发者应能定位失败边界。
  4. 比较小步合并与集中合并对等待时间、冲突和回退的影响,形成一项适合本组的工作流改进。
  5. 从干净目录构建并运行v0.1.0标签,形成版本日志、实机记录、已知限制和下一阶段议题。