Part of #273 ## Question 第一代(`GPT-VoiceCoding-legacy`,基准 commit `1d32845`)是怎样在每个 session 启动时完成注册并让 session 自报一个任务名的?要查清并写成事实: 1. **机制**:`SessionStart` hook 到 daemon 的注册链路,自报名字的提示词、校验(`labels.py`)、落库(`store.py`)、不可变规则,以及 Claude / Codex 两条 lane 各自的路径。入口线索:`bridge/hook.py:215-253`、`bridge/labels.py:20-70,73-106`、`bridge/daemon.py:1504-1544`、`bridge/store.py:1875-1902`、`bridge/hook.py:68-75,96-109,119-207,281-301`、`bridge/daemon.py:1192-1257`、`preflight.sh:65-107`。 2. **时序与耗时**:注册 + 起名在用户流程里处于什么位置,同步还是异步,等待多久,超时值是多少,超时后发生什么(用户反馈:经常超时,导致流程中断)。 3. **故障模式**:legacy issue tracker(`gh issue list -R okqixiaobao727-design/GPT-VoiceCoding-legacy --state all`)和 `docs/` 里关于起名 / 注册超时、名字缺失、重复起名的记录。 4. **legacy 自己对 ai-title 的测量**(`labels.py:73-84` 附近提到 30% 从不写、中位数晚 440 秒):测量方法、样本、结论。 5. **值得保留的部分**:哪些校验规则 / 不可变语义 / 产品判断值得带到新方案,哪些是要摆脱的(启动时同步动作、需要 session 配合、超时)。 结论写到 `docs/research/2026-09-07-legacy-session-naming-self-report.md`(本地文件),每条事实带 `legacy@1d32845:<file>:<lines>` 引用;摘要贴回本票作为 resolution comment 后关闭。不做方案设计,只给事实。
Activity
Simon-AI-coding commentedon Sep 7, 2026
研究已完成,事实写入
docs/research/2026-09-07-legacy-session-naming-self-report.md(本地文件)。以下是摘要。机制
SessionStarthook 注册时若session_label仍为空,daemon 回传的additionalContext会指示 session「在做其他任务动作之前」先执行bridgectl session-label --title '<标题>'自报一个简短、可读的任务标题(legacy@1d32845:bridge/hook.py:215-233)。这条指令对 Claude/Codex 两条 lane 文案完全相同——这本身就是修复「issue The unit suite fails at collection when the [acceptance] extra is installed: barefrom conftest importis captured by tests/acceptance/conftest.py #93」(Codex 原本独享自报,Claude 靠读自己的ai-title)的产物(hook.py:217-220)。labels.py:标题去空白后不能为空、不能多行;项目名不是配置项,而是对cwd跑git rev-parse --git-common-dir验证得到,任何异常都直接报错、绝不猜测(legacy@1d32845:bridge/labels.py:20-70,95-106)。set_session_label(store.py:1875-1902)是唯一写入口:未命名→写入;重复写相同值→幂等 no-op;写不同值→拒绝(StoreConflict),不可变。register_session的ON CONFLICT DO UPDATE明确不包含session_label列,所以重连/resume不会清空或触发重新命名(store.py:1644-1666)。session_label_duplicate: true,语音端被要求强制追问一个新的口头区分词,在拿到干净结果前不得继续 progress/relay/message/close(daemon.py:1049-1063;host.py:45-59)。unmanaged_session报错,根本走不到起名分支(daemon.py:1229-1234);Claude 无此前提。时序与超时
bridgectl session-label调用是 session 自己回合里「在处理用户真实请求之前」执行的一步工具/命令调用。hookTimeoutSeconds=3s(Claude Code/Codex 自己对 hook 子进程的超时);clientTimeoutSeconds=1.5s(session-label命令与 daemon 之间那一次本地 socket 往返的超时);launchRegistrationTimeoutSeconds=60s(这是另一件事——项目启动到 hook 注册的整个进程起壳预算,与逐 session 自报起名无关)(均见legacy@1d32845:config.plist:397-467)。launchRegistrationTimeoutSeconds是真被实测过并调大过的(观测到 5.7s/9.7s/22.7s 对 1.5s 预算,issue Step 0: put the written record in order — supersede the charter, point the repo at legacy #59),起名这一步没有类似的调优记录。hook.py:232)。一个还没起名就 Stop 的 session 是被架构预期并接受的正常状态,不会阻塞 Stop/progress(test_bridge.py:26312-26340)。故障模式
gh issue list --state all只有 27 个 issue(Build: seam contracts and Bridge Core state #1–The immediate Reply Window report emitted at registration is dropped because Bridge Core does not yet hold the Session, so an already-idle Session can stay stuck CLOSED #27),全文检索后没有一条专门记录「起名/注册超时」。代码注释里引用的 Step 0: put the written record in order — supersede the charter, point the repo at legacy #59/Prototype the Claude lane: official roster, built-in inbox socket and user-scope hooks, with no wrapper #71/Build 4/7 — Delivery receipts and settlement: inbox receipt, Codex verified, UNKNOWN never resends #77/Build 5/7 — Session naming: official names, immutable labels, self-report only for unnamed Codex #78/Build 7/7 — Duty bookkeeping: reconcile current state when Duty turns on #80/Redraw the domain for the bridge-only v1.0 (#68) #81/Prototype the Codex lane: the shared app-server daemon as both discovery and reach #82/Discover Sessions, lock the one inspection type, and make a registered Session reachable (#74) #92/The unit suite fails at collection when the [acceptance] extra is installed: barefrom conftest importis captured by tests/acceptance/conftest.py #93/Three comments still describe the pre-#74 / pre-#72 Session model #97/Claude lane: JSONL split on U+2028, approval_id paired with the wrong tool, and dead Sessions never evicted #98/Ask one Session how far it has got, and bound the answer once for both lanes (#76) #101/Read every JSONL record, name the call the dialog holds, and forget a Session that ended (#98) #102/Give a Session one name, composed once and never changed again (#78) #106/Probe codex 0.150.0: what changed on the surfaces we ride, and is there a simpler official route #107/Relay the Codex lane an instruction its own sandbox will not let it take (#105) #108 全部超出这个范围——它们指向开源之前一个没有迁移过来的私有追踪系统,在这个仓库里查不到原始 issue 内容,只能看到代码注释/docstring/测试里转述的结论。ai-title的旧方案会导致 Stop 通知在等一个永远不来的标题时被静默吞掉、后续 Stop 又覆盖前一个,「permanently silenced」(test_bridge.py:26312-26321)——这是被替换掉的旧机制的故障,不是自报新机制本身的故障。docs/里三份 ADR 都没提起名相关内容,代码注释引用的DESIGN.md在这个仓库的 git 历史里从未出现过,无法进一步溯源。legacy 对 ai-title 的测量
labels.py:78-83、test_bridge.py:28976-28978、test_bridge.py:30206-30209),全部指向「issue The unit suite fails at collection when the [acceptance] extra is installed: barefrom conftest importis captured by tests/acceptance/conftest.py #93」。git log -S"30%"/-S"median of 440"显示这两个数字在本仓库的第一个提交就已经原样存在——测量本身发生在这个仓库的历史开始之前。仓库里没有任何脚本、原始日志、样本量说明或方法论记录,这两个数字目前只能作为「引用来的既定事实」看待,不能独立复核。值得保留 vs 应当摆脱
保留(legacy 自己给出的理由):
store.py:1878-1888)。daemon.py:1536-1543)——这正是 任务名应该显示什么:Session Name 的 task 半边的来源规则 #273 想要的「地址 vs 名字」区分,legacy 已经在协议层做过一次。labels.py:27-70,100-104)。daemon.py:1049-1063;host.py:45-59)。store.py:1657-1663;daemon.py:1244-1247)。应当摆脱(legacy 自己的动机 + #273 已定的立场):
<project> · <短 thread id>展示名,不再要求 session 配合。详见
docs/research/2026-09-07-legacy-session-naming-self-report.md。