- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次) - .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…), 目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪 - .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/) - .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*) - .gitignore 补:备份件(*.bak-*) - 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
237 lines
15 KiB
HTML
237 lines
15 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>唤醒 · 无人值守可行性 —— 泳道图 + 事故链图(2026-09-30)</title>
|
||
<style>
|
||
:root{
|
||
--bg:#0f1115; --panel:#171a21; --panel2:#1d2129; --line:#2b313c;
|
||
--tx:#e6e8ee; --tx2:#a6adbb; --tx3:#727a8a;
|
||
--red:#ff5c5c; --redbg:#331a1c; --amber:#ffb454; --amberbg:#332616;
|
||
--green:#3ddc97; --greenbg:#122c22; --blue:#5aa9ff; --bluebg:#152232;
|
||
}
|
||
*{box-sizing:border-box}
|
||
body{margin:0;background:var(--bg);color:var(--tx);
|
||
font-family:ui-sans-serif,-apple-system,"Segoe UI","Microsoft YaHei","PingFang SC",sans-serif;
|
||
font-size:14px;line-height:1.6;padding:28px 32px 60px}
|
||
h1{font-size:20px;margin:0 0 6px}
|
||
.sub{color:var(--tx3);font-size:12.5px;margin-bottom:18px}
|
||
.verdict{background:var(--redbg);border:1px solid var(--red);border-left:4px solid var(--red);
|
||
border-radius:8px;padding:12px 16px;margin-bottom:8px}
|
||
.verdict b{color:var(--red)}
|
||
.verdict .ok{color:var(--green)}
|
||
.card{background:var(--panel);border:1px solid var(--line);border-radius:10px;
|
||
padding:18px 20px 22px;margin-top:18px}
|
||
.card h2{font-size:15px;margin:0 0 4px;color:var(--tx)}
|
||
.card .hint{color:var(--tx3);font-size:12.5px;margin-bottom:12px}
|
||
svg{display:block;max-width:100%;height:auto}
|
||
.lg{display:flex;gap:18px;flex-wrap:wrap;color:var(--tx2);font-size:12.5px;margin-top:10px}
|
||
.lg span i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:6px;vertical-align:-1px}
|
||
.t{font-family:ui-monospace,Consolas,"Courier New",monospace}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<h1>唤醒 · 无人值守可行性 —— 两张图</h1>
|
||
<div class="sub">2026-09-30 19:4x | 机制线·唤醒机制探索 | 会话 <span class="t">a202550c</span> | 配文:<span class="t">交付物/唤醒-无人值守可行性-20260930.md</span></div>
|
||
|
||
<div class="verdict">
|
||
<b>判定:不能</b> —— 「把<u>已经退出的那个会话</u>从外部叫起来续跑」结构上无路:网关口就长在 worker 进程里,worker 一走端口就走;唯一外部入口 <span class="t">POST /api/v1/runs</span> 又不带"选哪个会话"的能力。<br>
|
||
<span class="ok">但"无人值守"本身仍做得到</span> —— 形态是「无人值守地<b>新起一个会话</b>」(=自动化派棒,今天已在跑),代价:粒度最细 1 小时。
|
||
</div>
|
||
|
||
<!-- ══════════════ 图 1 · 泳道图 ══════════════ -->
|
||
<div class="card">
|
||
<h2>图 1 · 泳道图(角色 × 阶段)</h2>
|
||
<div class="hint">看"外部想唤它"这个动作落在哪一格 —— 第 ④ 列把网关口带走,第 ⑤ 列因此没有可投的地址。</div>
|
||
<svg viewBox="0 0 1220 560" role="img" aria-label="唤醒链路泳道图">
|
||
<defs>
|
||
<marker id="ar" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto">
|
||
<path d="M0,0 L9,4.5 L0,9 z" fill="#5f6a7c"/>
|
||
</marker>
|
||
</defs>
|
||
|
||
<!-- 列头 -->
|
||
<g font-size="12.5" fill="#a6adbb">
|
||
<text x="150" y="26" font-size="11.5" fill="#727a8a">角色 \ 阶段</text>
|
||
<text x="266" y="26">① 会话被激活</text>
|
||
<text x="476" y="26">② 回合进行中</text>
|
||
<text x="686" y="26">③ 回合结束</text>
|
||
<text x="896" y="26">④ worker 自行退出</text>
|
||
<text x="1106" y="26">⑤ 外部想叫醒它</text>
|
||
</g>
|
||
<line x1="150" y1="36" x2="1216" y2="36" stroke="#2b313c"/>
|
||
|
||
<!-- 行标签列 -->
|
||
<g font-size="12.5" fill="#e6e8ee">
|
||
<text x="8" y="88">宿主主进程</text><text x="8" y="104" font-size="11" fill="#727a8a">CliPrewarmPool</text>
|
||
<text x="8" y="178">CLI worker</text><text x="8" y="194" font-size="11" fill="#727a8a">(=会话宿主)</text>
|
||
<text x="8" y="268">网关口 (HTTP)</text>
|
||
<text x="8" y="358">外部程序</text><text x="8" y="374" font-size="11" fill="#727a8a">(想唤醒的一方)</text>
|
||
<text x="8" y="448">目标旧会话</text>
|
||
</g>
|
||
<line x1="150" y1="36" x2="150" y2="500" stroke="#2b313c"/>
|
||
|
||
<!-- 网格底 -->
|
||
<g stroke="#232833">
|
||
<line x1="150" y1="130" x2="1216" y2="130"/><line x1="150" y1="216" x2="1216" y2="216"/>
|
||
<line x1="150" y1="302" x2="1216" y2="302"/><line x1="150" y1="402" x2="1216" y2="402"/>
|
||
<line x1="150" y1="500" x2="1216" y2="500"/>
|
||
<line x1="360" y1="36" x2="360" y2="500"/><line x1="570" y1="36" x2="570" y2="500"/>
|
||
<line x1="780" y1="36" x2="780" y2="500"/><line x1="990" y1="36" x2="990" y2="500"/>
|
||
</g>
|
||
|
||
<!-- ④ 红列底纹 -->
|
||
<rect x="990" y="36" width="226" height="464" fill="#ff5c5c" opacity="0.055"/>
|
||
<!-- ⑤ 红列底纹 -->
|
||
<rect x="990" y="36" width="226" height="464" fill="none"/>
|
||
<rect x="804" y="36" width="186" height="464" fill="#ffb454" opacity="0.05"/>
|
||
<line x1="780" y1="36" x2="780" y2="500" stroke="#ffb454" opacity="0.35"/>
|
||
<line x1="990" y1="36" x2="990" y2="500" stroke="#ff5c5c" opacity="0.5"/>
|
||
|
||
<g font-size="12.5" fill="#c9cede">
|
||
<!-- 宿主主进程 -->
|
||
<text x="166" y="76">tryAcquire</text><text x="166" y="93">→ doActivate</text><text x="166" y="110">+ spawn 补池</text>
|
||
<text x="376" y="93" fill="#727a8a">(不干预)</text>
|
||
<text x="586" y="93" fill="#727a8a">(不干预)</text>
|
||
<text x="806" y="76" fill="#ff5c5c">child.on("exit")</text><text x="806" y="93" fill="#ff5c5c">⇒ 只打一条 warn</text>
|
||
<text x="806" y="110" fill="#ff5c5c">⛔ 不补池/不重拉</text>
|
||
<text x="1000" y="76" fill="#ff5c5c">无入口</text><text x="1000" y="93" fill="#ff5c5c">⛔ 不补池</text><text x="1000" y="110" fill="#ff5c5c">⛔ 不重拉</text>
|
||
|
||
<!-- CLI worker -->
|
||
<text x="166" y="160">起进程</text><text x="166" y="177">+挂网关口</text><text x="166" y="194" fill="#727a8a">:PORT 随进程诞生</text>
|
||
<text x="376" y="160">处理消息·跑工具</text><text x="376" y="177" fill="#727a8a">addHistory 不停</text>
|
||
<text x="586" y="160">生成收尾</text><text x="586" y="177" fill="#3ddc97">addHistory ✔</text>
|
||
<text x="806" y="160" fill="#ff5c5c">code=1 静默退出</text><text x="806" y="177" fill="#ff5c5c">stderr 空·非人为 kill</text>
|
||
<text x="806" y="194" fill="#ff5c5c">⇒ 端口也没了</text>
|
||
<text x="1000" y="177" fill="#ff5c5c">已不存在</text>
|
||
|
||
<!-- 网关口 -->
|
||
<text x="166" y="250">/live = 本会话</text>
|
||
<text x="376" y="250">writerOccupied=true</text>
|
||
<text x="586" y="250" fill="#727a8a">(同左)</text>
|
||
<text x="806" y="250" fill="#ff5c5c">✗ 随进程消失</text>
|
||
<text x="1000" y="250" fill="#ff5c5c">✗ 连不上</text>
|
||
|
||
<!-- 外部程序 -->
|
||
<text x="166" y="345" fill="#727a8a">—</text><text x="376" y="345" fill="#727a8a">—</text><text x="586" y="345" fill="#727a8a">—</text>
|
||
<text x="806" y="345" fill="#727a8a">—</text>
|
||
<text x="1000" y="330" fill="#ffb454">POST /runs → 202 接受</text>
|
||
<text x="1000" y="347" fill="#ffb454">但落到「它自己</text>
|
||
<text x="1000" y="364" fill="#ffb454">那个会话」</text>
|
||
|
||
<!-- 目标旧会话 -->
|
||
<text x="166" y="435">← 唯一一次被激活</text>
|
||
<text x="376" y="435">跑完它的回合</text>
|
||
<text x="586" y="435" fill="#ff5c5c">transcript 冻结</text>
|
||
<text x="806" y="435" fill="#ff5c5c">就此冻结</text>
|
||
<text x="1000" y="435" fill="#ff5c5c">零反应</text>
|
||
<text x="1000" y="452" fill="#ff5c5c" font-size="11">(md5 一字未变)</text>
|
||
</g>
|
||
|
||
<!-- 关键箭头 -->
|
||
<path d="M885 130 L885 140" stroke="#5f6a7c" marker-end="url(#ar)"/>
|
||
<path d="M1095 216 L1095 300" stroke="#ffb454" stroke-dasharray="4 3" marker-end="url(#ar)"/>
|
||
<text x="1002" y="492" font-size="11.5" fill="#727a8a">▲ 红格:④ 把网关口带走 ⇒ ⑤ 无处可投(对别的活网关投=落它自己的会话)</text>
|
||
</svg>
|
||
<div class="lg">
|
||
<span><i style="background:#ff5c5c"></i>断点/失效</span>
|
||
<span><i style="background:#ffb454"></i>看似成功、实则落错会话</span>
|
||
<span><i style="background:#3ddc97"></i>正常</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ══════════════ 图 2 · 事故链图 ══════════════ -->
|
||
<div class="card">
|
||
<h2>图 2 · 事故链图("想唤醒旧会话"实际怎么断的 + 哪几道防线缺席)</h2>
|
||
<div class="hint">★="有人在给它派活"这一瞬间;红格=静默丢单;橙格=202 假绿。</div>
|
||
<svg viewBox="0 0 1220 470" role="img" aria-label="唤醒失败事故链图">
|
||
<defs>
|
||
<marker id="ar2" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto">
|
||
<path d="M0,0 L9,4.5 L0,9 z" fill="#5f6a7c"/>
|
||
</marker>
|
||
</defs>
|
||
|
||
<g font-size="12.5">
|
||
<!-- 链节点 -->
|
||
<rect x="24" y="14" width="600" height="46" rx="8" fill="#171a21" stroke="#3ddc97" stroke-width="1.2"/>
|
||
<text x="40" y="34" fill="#3ddc97" font-size="11.5" class="t">19:00:19.720</text>
|
||
<text x="150" y="34" fill="#e6e8ee">宿主 tryAcquire → doActivate ⇒ 706d2476 拿到 worker(pid=47188)</text>
|
||
<text x="150" y="51" fill="#a6adbb" font-size="11.5">网关口 :PORT 随之诞生</text>
|
||
|
||
<path d="M324 60 L324 74" stroke="#5f6a7c" marker-end="url(#ar2)"/>
|
||
<rect x="24" y="74" width="600" height="34" rx="8" fill="#171a21" stroke="#2b313c"/>
|
||
<text x="40" y="96" fill="#a6adbb" font-size="11.5" class="t">19:00–19:09</text>
|
||
<text x="150" y="96" fill="#c9cede">该会话跑完它的整轮工作(会话日志连续增长)</text>
|
||
|
||
<path d="M324 108 L324 122" stroke="#5f6a7c" marker-end="url(#ar2)"/>
|
||
<rect x="24" y="122" width="600" height="46" rx="8" fill="#152232" stroke="#5aa9ff"/>
|
||
<text x="40" y="142" fill="#5aa9ff" font-size="11.5" class="t">19:09:16.304</text>
|
||
<text x="150" y="142" fill="#e6e8ee">★ resolveConfig input {"sessionId":"706d2476…"}</text>
|
||
<text x="150" y="159" fill="#5aa9ff" font-size="11.5">=宿主这边**确实**在给它准备一次运行 ⇒ 有人在派活</text>
|
||
|
||
<path d="M324 168 L324 182" stroke="#5f6a7c" marker-end="url(#ar2)"/>
|
||
<rect x="24" y="182" width="600" height="60" rx="8" fill="#331a1c" stroke="#ff5c5c" stroke-width="1.4"/>
|
||
<text x="40" y="203" fill="#ff5c5c" font-size="11.5" class="t">19:09:16.570</text>
|
||
<text x="150" y="203" fill="#ff5c5c">⛔ activated prewarm entry exited unexpectedly</text>
|
||
<text x="150" y="220" fill="#ff5c5c" font-size="11.5" class="t">code=1 signal=none stderr tail: <empty></text>
|
||
<text x="150" y="236" fill="#ffb454" font-size="11.5">⇒ 0.27 s 之内,那次"派活"就地蒸发(静默丢单)</text>
|
||
|
||
<path d="M324 242 L324 256" stroke="#5f6a7c" marker-end="url(#ar2)"/>
|
||
<rect x="24" y="256" width="600" height="46" rx="8" fill="#331a1c" stroke="#ff5c5c" stroke-width="1.4"/>
|
||
<text x="40" y="276" fill="#ff5c5c" font-size="11.5">此后</text>
|
||
<text x="150" y="276" fill="#ff5c5c">再没有任何 706d2476 的 doActivate / resolveConfig</text>
|
||
<text x="150" y="293" fill="#ff5c5c" font-size="11.5">⇒ 宿主不自愈(activated 退出=只 warn,不补不拉)</text>
|
||
|
||
<path d="M324 302 L324 316" stroke="#5f6a7c" marker-end="url(#ar2)"/>
|
||
<rect x="24" y="316" width="600" height="46" rx="8" fill="#332616" stroke="#ffb454" stroke-width="1.4"/>
|
||
<text x="40" y="336" fill="#ffb454" font-size="11.5" class="t">19:40:56</text>
|
||
<text x="150" y="336" fill="#e6e8ee">本棒把 id=706d2476 的 POST /api/v1/runs 打到另一个**活着的**网关</text>
|
||
<text x="150" y="353" fill="#ffb454" font-size="11.5">回 202 accepted、run 表 active=true ⇢ 看似成功</text>
|
||
|
||
<path d="M324 362 L324 376" stroke="#5f6a7c" marker-end="url(#ar2)"/>
|
||
<rect x="24" y="376" width="600" height="60" rx="8" fill="#331a1c" stroke="#ff5c5c" stroke-width="1.4"/>
|
||
<text x="40" y="397" fill="#ff5c5c" font-size="11.5" class="t">19:45:00</text>
|
||
<text x="150" y="397" fill="#ff5c5c">706d2476 transcript:230 行 / md5 7c404bfd… / mtime 19:09:15.929</text>
|
||
<text x="150" y="414" fill="#ff5c5c" font-size="12.5">▲ **一字未变** ⇒ 这一棒想做的事,结构上就做不成</text>
|
||
<text x="150" y="430" fill="#727a8a" font-size="11">(activeSessionId 全程仍是投递方自己的会话 a202550c)</text>
|
||
</g>
|
||
|
||
<!-- 右侧:缺席的防线 -->
|
||
<rect x="652" y="14" width="546" height="422" rx="10" fill="#1d2129" stroke="#2b313c"/>
|
||
<text x="672" y="40" font-size="13.5" fill="#e6e8ee">哪几道防线缺席</text>
|
||
<line x1="672" y1="52" x2="1178" y2="52" stroke="#2b313c"/>
|
||
|
||
<g font-size="12.5">
|
||
<circle cx="682" cy="78" r="11" fill="#331a1c" stroke="#ff5c5c"/><text x="682" y="82" fill="#ff5c5c" font-size="11.5" text-anchor="middle">1</text>
|
||
<text x="702" y="76" fill="#e6e8ee">投递没有"落到谁"的回执</text>
|
||
<text x="702" y="93" fill="#a6adbb" font-size="11.5">202 只说明"受理了";/status.activeSessionId 也不会因这次投递而变</text>
|
||
<text x="702" y="110" fill="#ffb454" font-size="11.5">⇒ 调用方无法判断"它到底有没有投到我要的那个会话"</text>
|
||
|
||
<circle cx="682" cy="146" r="11" fill="#331a1c" stroke="#ff5c5c"/><text x="682" y="150" fill="#ff5c5c" font-size="11.5" text-anchor="middle">2</text>
|
||
<text x="702" y="144" fill="#e6e8ee">activated 条目意外退出=只写一条 warn</text>
|
||
<text x="702" y="161" fill="#a6adbb" font-size="11.5">不补池、不重拉、不通知任何环节</text>
|
||
<text x="702" y="178" fill="#ff5c5c" font-size="11.5">⇒ 会话宿主没了,系统里没有一环会察觉,更不会自愈</text>
|
||
|
||
<circle cx="682" cy="214" r="11" fill="#331a1c" stroke="#ff5c5c"/><text x="682" y="218" fill="#ff5c5c" font-size="11.5" text-anchor="middle">3</text>
|
||
<text x="702" y="212" fill="#e6e8ee">网关没有"打开/激活某个会话"的端点</text>
|
||
<text x="702" y="229" fill="#a6adbb" font-size="11.5">会话控制器只有 list / live / workspaces / pins / rename / remove /</text>
|
||
<text x="702" y="246" fill="#a6adbb" font-size="11.5">history / replay / reply —— 唯独没有"打开"</text>
|
||
<text x="702" y="263" fill="#ff5c5c" font-size="11.5">⇒ 唯一有效的复活动因在桌面端,而它走 pipe,不是 TCP ⇒ 外部接不上</text>
|
||
|
||
<circle cx="682" cy="299" r="11" fill="#331a1c" stroke="#ff5c5c"/><text x="682" y="303" fill="#ff5c5c" font-size="11.5" text-anchor="middle">4</text>
|
||
<text x="702" y="297" fill="#e6e8ee">worker 存活时长没有下限保障</text>
|
||
<text x="702" y="314" fill="#a6adbb" font-size="11.5">今天实测:最短 28 s、多数 4–5 min(三天 40 / 55 / 28 次退出)</text>
|
||
<text x="702" y="331" fill="#a6adbb" font-size="11.5">idle 钩子要的"连续空闲 ≥60 s"正好落在 worker 生命的尾巴上</text>
|
||
<text x="702" y="348" fill="#a6adbb" font-size="11.5">⇒ 18:55:00.210 那次成功,是小概率命中,不是稳定能力</text>
|
||
|
||
<text x="672" y="386" fill="#727a8a" font-size="11.5">结论:这四条都不是"没做好",是"结构上不存在"——</text>
|
||
<text x="672" y="404" fill="#727a8a" font-size="11.5">故"唤醒同一个旧会话"无法实现;能实现的是"无人值守地新起一个会话"(自动化,1 小时粒度)。</text>
|
||
<text x="672" y="424" fill="#5aa9ff" font-size="11.5">唯一能改变此判定的未知量:code=1 到底是"回合结束被主动回收"还是"崩溃"。</text>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|