Choose a model for the work you need to doMe
← All case studies

给AI长会话做一次离线体检:本地JSONL存档v3/v4双口径解析与重命名原子写入五步验证

Article content is shown in its original language.

山海技术探索:基于YeqingTang/dsh-session-flow固定Commit源码,在隔离沙箱中验证v3/v4工具报错双口径解析、子代理血缘关联与重命名原子持久化。

这是一篇山海技术探索:先分清哪些已核验、哪些未在宿主实测

本文是一篇山海技术探索。在开始任何操作前,先向读者交代清楚证据边界:我们已核验了开源仓库 YeqingTang/dsh-session-flow(版本1.4.4,固定Commit哈希 efdb0123f95ba0e9965406963e0eae7c07533be8,Apache-2.0协议)的 package.json、cordis.patch.yml 与核心解析源码,并在本机隔离沙箱中完成了v3/v4双格式会话JSONL解析、子代理血缘关联、工作区路径防穿透清洗以及重命名表原子写入的局部验证(耗时0.0015秒,API费用0美元);但本文尚未在真实DeepSeek Harness(DSH)v0.2.1桌面客户端内执行插件安装、Profile重启、3秒实时轮询UI渲染以及LLM摘要接口调用,因此不可将本文视为完整宿主环境的运行验收证明。

为什么这项探索值得开发者动手一试?因为无论是使用DSH、Claude Code还是自研智能体框架,本地会话日志都会随着版本迭代发生Schema结构漂移。例如DSH从v3升至v4存档时,工具调用报错字段从嵌套内容块移到了消息顶层,导致旧版统计脚本出现漏报。把 dsh-session-flow 的“双口径解析+索引与用户资产解耦”机制抽离成可独立验证的五步离线脚本,能帮研发团队在不惊动生产环境的前提下,安全体检本地智能体日志。

最终目标、环境前提与输入样本准备

【最终目标与验收标准】在本地隔离目录中构建一套零外部依赖的会话日志体检与索引脚本,确保:1)同时准确识别v3嵌套结构与v4顶层结构的工具调用报错(tool_errors_detected均为1);2)正确提取子代理会话的 parentSessionId 血缘指向;3)拦截包含 ../ 的恶意工作区名称;4)清理索引缓存文件后,用户自定义会话重命名文件 renames.json 完好无损。

【适用系统与版本前提】macOS 12+ / Linux / Windows 10+;本地验证脚本使用 Python >= 3.10 标准库(零第三方pip依赖,0元API费用);若后续需运行原仓库 Node.js 解压模块,则宿主机 Node.js 版本必须满足 ^22.19.0 或 >= 24.0.0(以提供 node:zlib.zstdDecompressSync 支持)。

【输入样本】两份隔离构造的多轮智能体会话行文件:一份模拟 v3 格式主会话(session-root-001/session.v3.jsonl),一份模拟派生自该主会话的 v4 格式子代理会话(session-child-002/session.v4.jsonl)。

步骤一:检视原仓库补丁声明并创建隔离沙箱目录树

第一步,打开终端进入测试工作区,核对原仓库固定Commit efdb0123f95ba0e9965406963e0eae7c07533be8 下的 cordis.patch.yml 与 package.json。确认其仅声明挂载 id: dsh-session-flow,且运行时入口为 lib/host.js 与 lib/client.js,不包含任何 postinstall 自动执行脚本。

随后在本地测试目录下创建模拟的会话存档目录与索引输出目录:执行 mkdir -p session_flow_isolated_sample/.dsh/sessions/demo-workspace 与 mkdir -p session_flow_isolated_sample/.dsh/session-flow。

【预期中间结果】目录树创建完成,原始存档区(sessions)与插件缓存区(session-flow)在物理路径上完全分离,确保后续缓存清理操作绝不触碰原始会话记录。

步骤二:写入v3与v4双版本会话样本并建立子代理血缘字段

第二步,在 demo-workspace 下分别创建主会话文件夹 session-root-001 与子代理文件夹 session-child-002,写入两代格式的 JSONL 事件流样本。

在 session.v3.jsonl 的首行 header 中写入 version: 3 与 sessionId: session-root-001;在第三行模拟一次读取配置文件失败的工具返回,按 v3 规范将 role 设为 user,并在 content[0] 字典内写入 type: tool-result 与 isError: true。

在 session.v4.jsonl 的首行 header 中写入 version: 4、sessionId: session-child-002 以及指向主会话的 parentSessionId: session-root-001;在第三行按 v4 规范将顶层 role 径直设为 tool,并在 data 顶层写入 isError: true。

【预期中间结果】两份样本文件落盘成功,分别代表跨版本升级前后的真实日志形态与父子派生关系。

步骤三:运行v3/v4双口径解析器与路径提取过滤规则

第三步,参照原仓库 lib/archive.js 的解析逻辑,执行双口径扫描函数 parse_session_jsonl。解析器逐行读取 JSON 对象:遇到 type 为 header 时提取版本号、当前会话ID与父会话ID;遇到消息行时,若 role 为 user 且 content[0].type 为 tool-result,则归入 v3 工具调用并检查 content[0].isError;若顶层 role 为 tool,则归入 v4 工具调用并检查顶层 data.isError。

同时执行文件路径降噪提取(对应原仓库 looksLikePath 规则):仅提取键名匹配 filePath、path、targetPath 且长度在 2 至 200 字符之间、不含通配符 * 的字符串,写入 files_indexed 集合,从而支持后续按 file: 前缀做跨会话精准检索。

【预期中间结果】v3 主会话与 v4 子代理会话的工具报错计数均准确输出为 1,子代理 parent_session_id 准确指向 session-root-001,关联文件路径 src/gateway/config.ts 与 src/gateway/router.ts 被完整收录。

步骤四:验证工作区名称防穿透清洗与INDEX_VERSION=6缓存落盘

第四步,参照 lib/index-store.js 的 workspaceIndexFile 函数,测试当工作区名称包含恶意目录穿越字符(例如传入 ../../etc/passwd)时的文件名清洗逻辑:使用正则表达式将所有非字母、数字、点号、下划线与连字符的符号统一替换为下划线 _,并将长度截断在 120 字符以内。

验证通过后,将步骤三解析出的两个会话摘要封装进带有 version: 6(即 INDEX_VERSION = 6)标识的字典中,写入 .dsh/session-flow/index-demo-workspace.json。

【预期中间结果】恶意入参 ../../etc/passwd 被安全转换为 index-.._.._etc_passwd.json,不含任何路径分隔符 /,无法逃逸出 .dsh/session-flow 目录。

步骤五:执行重命名表tmp+rename原子写入与清理缓存解耦测试

第五步,参照 lib/renames.js 验证用户资产保护机制。构造一条长度超过120字符的会话自定义标题,先按 MAX_RENAME_LENGTH = 120 截断,再将其写入临时文件 renames.json.tmp,随后调用操作系统级原子替换(replace / rename)覆盖为正式的 renames.json。

接着模拟用户在插件界面点击“清理全部缓存”:径直删除 .dsh/session-flow/index-demo-workspace.json 索引文件,随后再次读取 renames.json 并核验内容。

【最终输出检查】测试脚本输出 session_flow_local_test.json,确认 v3_v4_dual_error_schema_verified、subagent_lineage_linked、workspace_name_sanitized、renames_atomic_write_and_cache_decoupled 四项安全断言全部为 true,网络端口打开数为 0。

常见报错恢复、安全隐私边界与升级为已验证方法的条件

【常见报错与恢复办法】1)若在 Node.js 环境中运行原仓库报 TypeError: zstdDecompressSync is not a function,说明当前 Node 版本低于 22.19.0,需使用 nvm 或 fnm 升级至 Node 22.19+ 或 24.x;2)若发现旧版本会话工具报错统计为 0,删除 ~/.dsh/session-flow/ 下对应的 index-*.json 文件,插件会在下次读取时按 INDEX_VERSION = 6 自动触发全量重扫;3)若 renames.json 因磁盘断电损坏,原仓库 loadRenames 函数会自动捕获异常并回退为空表告警,不会阻塞主会话加载。

【安全、隐私与费用边界】本地规则摘要与全文检索完全在本地磁盘闭环运行,零费用、零外发;若开启 LLM 摘要模式,请勿对包含未脱敏生产密钥或客户隐私的会话触发云端摘要。

【何时可升级为已验证方法】当后续在真实 DSH v0.2.1 桌面宿主环境中完成 cordis.patch.yml 挂载、一次性 Profile 重启、验证前端 3 秒轮询状态条与 ZIP 分卷报告下载且无回归报错后,本探索即可正式升级为“山海实用局”已复现方法。


原稿日期:2026-10-13。

Copyright removal requests

This article shares an AI use case. Rights to the original text and materials belong to their authors. Contact us to request removal of infringing content.

Contact email:jadename.zhou@gmail.com
Explore moreAgents & automationcase studies →