:从“可信承诺“到“可证明不变量“的完整实现指南)
Serial Studio 会话可复现性验证Spec 0044从可信承诺到可证明不变量的完整实现指南【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio会话数据库Session Database在 Serial Studio 中保存原始设备字节流与解释它们的项目配置本应让任何已归档会话都能被重新生成和审计。但长久以来这只是产品宣传中的一句承诺没有任何机制用归档原始字节重新推导处理结果并与捕获时记录的值做比对。本文基于仓库内 Spec 0044 及其配套计划、任务清单和真实源码完整讲解 Serial Studio 会话可复现性验证Session Reproducibility Verification的设计动机、需求规格、验收标准与落地实现读者读完后可以掌握验证功能在 UI/CLI/API 三端的调用方式、指纹与判定机制的底层原理以及如何用测试套件证明会话 X 在版本 B 下仍然可复现。一、背景会话数据库的承诺与验证缺口Serial Studio 的会话数据库Session DatabasePro 功能在架构上只依赖一句话的承诺它同时存储了原始设备字节和解释这些字节的项目配置因此任何归档会话都可以被重新生成并审计。但 Spec 0044 明确指出这至今只是一个 promise承诺而不是一个被验证过的不变量demonstrated invariant产品中没有任何环节会从归档原始字节重新推导处理值并与捕获时记录的值做比较。也就是说如果发生以下任一变化用户将无从察觉直到审计员发现解析器parser逻辑变更数据变换transform逻辑变更区域设置 / 格式化逻辑变更数值回归numeric regression导致相同字节产生不同结果。对于监管严苛、工业级的受众——测试台架、校准实验室、飞行测试遥测——静默漂移silent drift恰恰是他们购买这类工具想要规避的故障模式。更关键的是这个缺口在今天是可以被立即验证的一个已归档会话完整携带了原始字节、每个数据集记录的原始值与最终值以及完整项目 JSON——一切从头重放解释所需的数据都已齐备。然而重放replay故意只读取记录的最终值因为变换的实时输入已不存在无法重跑。于是唯一能证明可复现性的路径从未被真正走过。一个内建的、机械化的回归检查能把我们信任它升级为我们能展示它——对这个受众群体而言这比任何新控件都有价值。该问题的完整论证见 doc/claude/specs/0044-session-reproducibility/spec.md。二、核心目标验证流程、三态结论与诚实原则Spec 0044 定义了五个核心目标构成整个功能的行为契约按需验证用户可以从会话浏览界面选中一个已归档会话运行一次验证流程verification pass用当前构建 归档的项目配置重新解释归档原始字节。三态结论流程必须产出清晰结论reproduced可复现重新生成的值与记录值完全匹配diverged已发散不匹配并展示第一批分歧数据集、时间戳、记录值 vs 重新生成值not mechanically verifiable无法机械化验证会话依赖未被捕获的输入并点名具体原因。捕获时指纹新会话在捕获时记录足够的指纹材料记录流的内容哈希、应用版本、格式版本使后续验证能说明变了什么而不只是有东西变了。结论持久化验证结果可与会话一同存储并随时复检实验室可以在不保留旧二进制的情况下演示会话 X 在版本 A 下捕获在版本 B 下仍可复现。诚实优先于绿色勾号处理管线依赖未捕获实时状态如表驱动的变换、控制脚本交互、设备往返的会话应如实报告——检查绝不宣称它没有机械化建立的可复现性。三、非目标明确边界防止过度承诺Spec 对不做的事给出了同样严谨的定义这在工程上至关重要不是实时捕获的确定性保证。检查只证明存储的原始字节 存储的配置能重新生成存储的输出不涉及时序、采样或物理测量链路。文档必须明确说明这一点与非安全功能免责声明相邻但独立。不是格式冻结 / 格式文档。发布带迁移规则的项目文件与会话数据库格式版本化规范是独立的后续 spec本 spec 只消费已有的格式版本戳并在新会话中记录应用/格式版本。不是校准记录。校准作为一等对象是单独的后续 spec。不对旧会话做追溯魔法。此功能之前捕获的会话缺少指纹只能做尽力而为的验证仅值比较或诚实的捕获不充分结论——不虚构置信度。不增加实时捕获成本。指纹之外不向捕获路径添加任何逐帧工作且不触碰仪表盘热路径。不验证 CSV/MDF4 导出。那些是单向导出范围仅限会话数据库。四、需求规格R1–R9可验证的行为契约Spec 0044 用九条需求把目标落实为可测试的行为编号需求核心要点R1按需验证会话浏览 UI 中可对任意已完成的归档会话调用验证可复现性流程离线运行无设备连接不得干扰正在进行的实时捕获或已打开的重放R2从原始字节重新解释用归档项目配置对归档原始字节流重新运行帧提取与解析——使用与实时路径相同的解释引擎而非并行重实现——产出各数据集的重生成值R3比较与结论重生成值与记录值比较数值在存储的数值表示上按位精确bit-exact文本精确比较仅当每个可比较读数都匹配时才判reproduced否则divergedR4分歧报告diverged 结论至少点名受影响的数据集、每数据集不匹配读数数量、每数据集首个不匹配时间戳、记录值、重生成值、产生该值的解释阶段解析 vs 变换便于定位根因R5捕获时可复现性分类每个新会话记录其处理管线是否机械化自包含使用了未归档输入特性的会话由实时数据表驱动的逐数据集变换、变更解析状态的控制脚本、任何未存入会话的解释输入按特性标记为不可机械化验证验证时报告该分类而非给出虚假结论R6捕获时指纹每个新会话存储原始字节流与记录值的内容哈希content hash、应用版本与会话格式版本验证据此区分归档自捕获后已变更与当前构建对同一归档解释不同R7持久化验证记录每次验证运行向会话追加一条存储记录验证时间、验证应用版本、结论、分歧摘要会话 UI 显示最新结论R8旧会话兼容早于本功能的会话做尽力而为验证在存在记录值的地方重新解释并比较原始字节结论标注为 legacy无指纹、分类未知而非直接拒绝R9可脚本化验证流程可通过既有外部自动化面调用返回与 UI 相同的结论与分歧详情实验室可据此在自己的 CI 上把关所有归档会话仍然可复现五、验收标准AC1–AC8可演示的证据清单Spec 为每条需求都配了可执行、可观察的验收标准多数通过 pytest 集成测试完成由维护者在运行中的应用 API 服务器上执行AC1从合成数据源捕获会话Native 与 JS 解析器两种变体关闭后在同一构建上运行验证结论reproduced零分歧。对应 R1/R2/R3/R9AC2在归档副本中篡改一条记录读数验证报告diverged点名数据集、数量 1、精确的记录/重生成值对——且指纹检查将其归因于归档被修改。R3/R4/R6AC3篡改归档项目配置副本如更改变换常量验证报告diverged并将分歧归因于解释而非归档损坏。R4/R6AC4捕获一个使用数据表驱动变换的会话会话被标记为不可机械化验证并给出原因验证返回该分类而非reproduced。R5AC5pre-0044 会话文件可验证出带 legacy 限定的结论不崩溃、不拒绝。R8针对入库的旧版 fixtureAC6实时捕获进行中运行验证既不阻塞捕获也不损坏任一数据库维护者确认实时仪表盘行为不受影响。R1destructive 标记的 pytestAC7结论与分歧摘要跨应用重启持久化并在会话 UI 中重新显示。R7AC8--benchmark-hotpath门禁不变捕获路径新增内容在仪表盘路径上零逐帧成本。CI 门禁约束六、约束与不变量决定性的设计红线Spec 对实现划定了不可逾越的边界理解这些约束是读懂后续源码的关键决定性约束验证必须复用真实解释管线。一个仅用于检查的第二套实现自身会漂移检查检测到的分歧必须是实时用户会看到的分歧。推论验证离线运行在当前构建的引擎上因此必须能容忍应用可加载的每一种归档配置。诚实结论优先于完整覆盖。任何无法机械化重新推导的会话都被分类绝不近似。无容忍窗口、无差不多就行的数值模糊——产品主张是存储表示的位稳定性构建已把 IEEE 稳定数学钉为不变量。热路径零回归。不向仪表盘路径添加任何逐帧内容捕获端指纹必须尊重既有捕获架构解析路径上无逐帧分配、锁或信号并守住 256 kHz CI 门禁。重放语义不变。既有会话重放继续读取记录的最终值验证是独立流程不得改变重放行为或重新记录任何内容。归档是只读证据。验证绝不修改记录的会话数据唯一允许的写入是追加的验证记录与新会话的捕获时指纹。旧数据库必须继续打开。架构变更必须与既有会话数据库向后兼容增量迁移pre-0044 归档永远不能被渲染为不可读。Pro 功能。会话数据库是 Pro 功能验证在同一门禁下发布试用以同 Pro 行为。标签诚实。面向用户的文案必须说明检查证明了什么、没证明什么无确定性保证、非安全功能、非校准权威。七、实现方案从 Spec 到源码Spec 文档本身刻意不包含实现细节那是 plan.md 的职责但仓库中的 plan、tasks 与真实源码已经把方案完整落地。以下结合源码逐层展开。7.1 总体架构子进程验证复用真实管线核心决策在 doc/claude/specs/0044-session-reproducibility/plan.md 中给出验证作为应用自身二进制的一个子进程运行--verify-session复用--benchmark-hotpath已经验证过的无头模式——由 CLI.cpp 通过ModuleManager::instantiateCoreModules()构建固定的组合根composition root然后在进程内驱动真实管线。验证器执行的完整流程见Sessions::Verifier::run()Verifier.cpp打开归档只读openArchive()以QSQLITE_OPEN_READONLY打开归档数据库Verifier.cpp保证归档作为证据的只读性。加载会话loadSession()读取会话行按指定 ID 或最新已完成会话、project_json、列映射与指纹列。关键容错pre-0044 归档中指纹列不存在时视为 legacy 捕获而非错误Verifier.cpp。完整性阶段verifyIntegrity()用与捕获端共享的规范哈希代码重算raw_bytes与readings的 SHA-256与存储摘要比对——不匹配即归因于归档被修改对应 AC2无摘要的 legacy 会话跳过此阶段并限定结论Verifier.cpp。分类阶段classifySession()依据repro_class判断是否存在控制脚本、虚拟数据集等不可机械化验证因素。重新解析阶段reparseSession()用ProjectModel::loadFromJsonDocument()加载归档项目为每个归档设备构建一个IO::FrameReader配置来自ConnectionManager::buildFrameConfig()按raw_id顺序把raw_bytes块喂入FrameBuilder::hotpathRxFrame/hotpathRxSourceFrame()——与实时会话ConnectionManager::onFrameReady的路由完全一致。重生成值通过未修改的Sessions::Export汇入一个临时数据库ss-verify-regen-pid.db确保重生成读数由字节级相同的生产路径写出。SQL 序列比对对每个unique_id用ROW_NUMBER() OVER (ORDER BY reading_id)生成两侧序列并连接逐行做位精确数值比较与精确文本比较原始列不匹配归因于解析parse仅最终列不匹配归因于变换transform。帧数不匹配则短路为 count-mismatch 分歧并引用归档的丢帧/溢出统计详见下文风险部分。结论与持久化settleVerdict()汇总结论并输出 JSON 报告appendVerificationRecord()向归档数据库追加一条verifications记录临时重生成库默认删除--verify-keep-regen可保留作调试产物。7.2 捕获端指纹规范序列化与 SHA-256指纹的规范字节布局实现在 BlockFingerprint.cpp供捕获端ExportWorker与验证端Verifier共享杜绝两处实现漂移原始块hashRawChunkLE64 时间戳 LE64 设备 ID LE64 数据长度 原始字节BlockFingerprint.cpp读数行hashReadingRowLE64 时间戳 LE64 unique_id 原始/最终 double 以 IEEE-754 位模式LE64写入 原始/最终字符串按 UTF-8 长度前缀写入 is_numeric 字节BlockFingerprint.cpp块行hashBlockRowspec 0055 起的块式存储unique_id、t0_ns、dt_ns、frames 及各 blob 的长度前缀内容。捕获端在ExportWorker工作线程内维护两个增量QCryptographicHashSHA-256原始哈希在writeRawBytes内按raw_id顺序逐块更新读数哈希在bindAndInsertReading内逐行更新——不触碰主线程帧路径无逐帧分配/锁/信号对应 AC8 热路径门禁。finalizeSession()将两个摘要连同app_versionAPP_VERSION、capture_formatDatabaseManager::kCaptureFormatVersion当前为 2、repro_classJSON 与丢帧/溢出计数器写入会话行见 Export.cpp。7.3 数据模型增量迁移与验证记录表数据模型在 DatabaseSchema.cpp 中以纯增量迁移实现沿用既有migrateColumnsTable模式仅ALTER TABLE ... ADD COLUMN与CREATE TABLE IF NOT EXISTS无任何数据破坏性语句sessions新增可空列raw_sha256、readings_sha256、app_version、capture_format、repro_classJSON、frames_dropped、overflow_bytesDatabaseSchema.cppNULL legacy 捕获R8。新表verificationsappend-onlyverification_id、session_id、verified_at、app_version、verdict、detail_json并建idx_verifications_session索引DatabaseSchema.cpp。PRAGMA user_version在创建/迁移时置为文件级格式版本号。这样的设计使每个 pre-0044 归档保持可读验证记录随会话文件一起移动spec 明确允许追加验证记录。7.4 判定逻辑诚实结论的守卫链结论裁决在Sessions::Verifier::decideVerdict()Verifier.cpp采用守卫子句优先级控制脚本优先会话使用过控制脚本且无分歧 →not_verifiable注明控制脚本结果每次运行可能不同无法机械化检查分歧压过一切任何分歧 →divergedConsoleOnly 会话无解释管线仅做原始完整性检查摘要匹配 →reproduced否则not_verifiable并注明仅原始控制台数据只有存储数据本身被检查部分跳过存在依赖未存储数据的值 →partial注明已验证除依赖未存储数据的值外全部匹配→reproduced。进程退出码是二元的0 reproduced非零 其他细粒度结论reproduced/diverged/partial/not_verifiable/error完整保留在 JSON 报告中供测试与实验室 CI 消费。7.5 CLI、API 与 UI 三端入口CLI新增--verify-session db、--verify-session-id n默认最新已完成会话、--verify-keep-regenrunSessionVerification()镜像runHotpathBenchmark()的组合根模式无头平台、licensing 优先、JSON 输出到 stdout。--verify-session被列入isCliEarlyExit()的早期退出标志CLI.cpp。APIsessions.verifyverb 在SessionsHandler中实现BUILD_COMMERCIAL门控采用处理器基础设施既有的异步长操作约定异步启动 完成事件/轮询交付与 CLI stdout相同 schema的结论 JSONR9使 pytest 与实验室 CI 只消费一种格式。UISessionDetail.qml提供Verify reproducibility操作与结论面板结论、验证时间、验证版本、逐数据集分歧列表、分类原因、legacy 限定、诚实标签文案SessionList.qml按会话显示最新结论徽章。父进程通过DatabaseManager::verifySession()用QProcess异步拉起子进程piped stdout不阻塞 GUI 线程WAL busy_timeout已覆盖子进程追加写入。八、测试与验证计划如何证明仍然可复现规格的验收标准由 tests/integration/test_session_verification.py 覆盖pytest运行中的应用 API 服务器关键用例包括AC1 往返验证通过 API 驱动捕获合成会话Native JS 变体调用sessions.verify断言结论reproduced、零分歧test_js_session_reproduced、test_quickplot_native_session_reproduced等AC2 读数篡改复制 fixture用 sqlite3 翻转一条readings行断言diverged、点名数据集、数量 1、精确值对、归因archive-modifiedtest_tampered_reading_attributed_to_archiveAC3 配置篡改复制 fixture篡改存储project_json中的变换常量断言diverged且归因interpretation完整性哈希排除project_json故读数哈希仍匹配分歧落在变换阶段AC4 分类结论记录含表驱动虚拟数据集的会话断言返回分类结论而非reproducedAC5 legacy 验证入库的 pre-0044 fixture 以限定 legacy 结论验证exit 0 路径、不崩溃AC6 并发安全destructive 标记实时捕获进行中并发运行验证断言捕获行持续写入且两个数据库均完好AC7 持久化重启应用后从verifications表读回结论徽章。另外tests/fixtures/sessions/README.md 记录旧版 fixture 的出处维护者用真实构建生成保证 AC5 的可复现性。全部改动文件需通过python scripts/code-verify.py --check静态检查--benchmark-hotpath全量运行不得回归AC8。九、设计权衡、风险与后续开放问题9.1 关键权衡来自 plan.md决策点备选方案选定方案与理由验证运行位置(A) 子进程独立组合根(B) 实时应用内进程内(C) 独立重解析器A——B 会摧毁用户实时会话状态并给热路径加分支违反 R1C 是会漂移的检查器分叉违反决定性约束。A 复用基准测试验证过的无头模式重生成值捕获方式临时库重录未修改的Sessions::Export SQL 比对内存比较器 sink临时库重录——零新帧路径代码写路径与生产字节一致重生成库是可持久调试产物--verify-keep-regen指纹算法SHA-256QCryptographicHashxxHash/FNVSHA-256——防篡改且跨平台稳定工作线程上速度非瓶颈行对齐键每 uid 序列ROW_NUMBERoverreading_id时间戳匹配序列——重生成时间戳是合成的记录timestamp_ns按帧单调化序数是唯一稳定的连接键结论存储归档库内verifications表旁车文件库内——随证据移动、随文件移动存活spec 明确允许追加验证记录分类深度捕获时标志控制脚本、变换表捕获、逐数据集is_virtual脚本代码静态分析标志——廉价、诚实、信号现成脚本分析是过度工程且会带来虚假置信9.2 风险与缓解捕获端丢帧破坏序列对齐高码率下 FrameConsumer 队列溢出记录流是重生成流的子集缓解为持久化工作线程丢帧计数与 FrameReader 溢出字节计数不匹配时结论为diverged: count mismatch并引用这些统计使有损捕获与解释变更可区分——不做模糊重对齐诚实优先于绿色勾号。buildFrameConfig暴露仅加访问器不动逻辑不新增instance()/SessionContext::current()调用点单例普查保持平稳。Windows GUI 子系统 stdoutQProcess 直接管道处理句柄非控制台附加父进程派生子进程不受/SUBSYSTEM:WINDOWS坑影响。Explorer 持有归档时并发追加WAL busy_timeout5000已是项目标准追加仅在结论时刻发生一次。子进程许可组合根先构建 licensingspec 0042验证在 CLI/处理器/UI 入口均受 Pro 门控GPL 构建通过BUILD_COMMERCIAL完全不编译该代码。9.3 遗留开放问题spec 原文Q1 混合会话结论粒度多源会话中一个源为表驱动、其余自包含时用单一会话级分类还是按源/按数据集结论推荐逐数据集分类向上汇总为会话结论reproduced除 N 个不可验证数据集外。Q2 帧提取的原始流保真度重提取必须产出与会话当时相同的帧边界字节流拼接是否对所有帧检测模式都是充分真值若存在依赖归档未捕获的到达时序的模式这些会话应归入 R5 分类。Q3 结论的呈现范围推荐本 spec 仅覆盖会话 UI 自动化 API可打印/可导出的验证报告以后复用既有报告工具。Q4 指纹算法与存储形态刻意延后到 plan 阶段spec 仅要求内容寻址、跨平台稳定、捕获成本足够低。Q5 批量验证一个动作验证库内所有会话是本期还是后续推荐后续——R9 已允许脚本循环。十、总结Spec 0044 把会话数据库从存档升级为可证明的证据捕获端以零热路径代价记录 SHA-256 指纹、应用版本与可复现性分类验证端以子进程复用真实解释管线对归档原始字节重新解释并通过 SQL 序列比对给出reproduced/diverged/partial/not_verifiable的诚实结论结论随会话持久化实验室可在不保留旧二进制的情况下持续把关所有归档会话仍然可复现。整套设计以诚实结论优先于完整覆盖和验证必须复用真实管线为决定性约束配套的验收标准与 pytest 套件把我们信任它变成了可演示、可审计、可脚本化的事实。本文基于 spec.mdSpec 0044、plan.mdPhase 2 技术设计与 tasks.mdPhase 3 任务清单并对照 Verifier.cpp、BlockFingerprint.cpp、DatabaseSchema.cpp、Export.cpp、CLI.cpp 与 test_session_verification.py 等真实源码交叉印证。【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考