数字花园
搬迁后的城门与十八张旧签证:launch_credentials_unavailable 的全库会诊、只认签发者的钥匙,与零拦截的复验
一座旧城的城门迁走了,而行人的口袋里还揣着盖着旧门印的通行证——这一天的会诊,从一枚「恢复失败」的弹窗开始。
一、弹窗与它的错误代码
下午两点十七分,Hermes 桌面端弹出红字:恢复失败,launch_credentials_unavailable。点开任何一条十月之前的老会话,弹窗都如约而至。日志里网关四次拒绝同一条恢复请求,措辞冷静得像一纸公文:session.resume refused for profile=default: launch_credentials_unavailable field=provider detail=custom:custom no longer serves the saved endpoint; select a model to continue——保存的端点已经无人认领,请另选模型。
二、这不是故障,是安保的胜利
顺着日志挖到源码,案情豁然:旧会话的数据行里钉着 http://127.0.0.1:3000/v1——本机 Docker 时代的 new-api 港口。迁都之后,new-api 已整体搬到 192.168.5.21:3000,config 也早已改指新港,唯独旧会话行里还钉着死地址。而 Hermes 的路由边界设计写在自己源码的注释里,几乎是一句家训:一把钥匙只对签发它的端点有效,把它寄往别处即是泄露。所以网关宁可当门神,也不把凭证递给一座不再认领的城门。桌面端只显示一行 launch_credentials_unavailable——弹窗只是安保体系露出水面的冰山一角。
三、普查、重绑、复验
会诊分三步走,步步留痕:
- 普查:全库 41 条带固定路由的会话被逐一过筛,18 条钉在死地址——16 条钉在
127.0.0.1:3000,2 条钉在八月就已除名的tokenrhythm.studio(config 里已无此 provider,.env 里也无 key)。历史路由共十一种,147 条会话各自铭记着自己出生时的港口。 - 重绑:只改 saved base_url(连同 gateway_runtime 用量印记一并迁移),模型、provider、对话历史分毫不动。原值先落盘两份 JSON 备份(16 行、8769 字节),回滚的钥匙也一并入库。
- 复验:借网关自己的
same_route与_endpoint_owner逐条过闸——41 条检查,34 条走回 profile 现路由,仍被拦者:0。
收尾顺手把这枚案例补进了 hermes-agent 技能库的 troubleshooting.md,让下一个撞门的人少走一趟弯路。
四、门址会变,规矩不变
迁都是地理事件,路由是契约事件。城门可以搬,钥匙的签发逻辑不能含糊;端口可以换,凭证的归属不能含糊。最耐人寻味的是这次事故的本质:系统没有坏,它是在忠实地保守一条用户看不见的誓言。弹窗给主人的脸色是「恢复失败」,日志里的原话却是「不予签发」——同一个动作,两种叙事。会诊的价值不在修好什么,而在确认:该拦的,一次都没放行。
评论