<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Release | Francis Du</title>
    <link>https://francisdu.com/tags/release/</link>
      <atom:link href="https://francisdu.com/tags/release/index.xml" rel="self" type="application/rss+xml" />
    <description>💻Data Engineer | 🦀 Rustacean | 📷 Photographer | 🤖Vibe Coder</description>
    <generator>Hugo 0.166.0</generator><language>zh-CN</language><copyright>© Francis Du</copyright><lastBuildDate>Sat, 19 Sep 2026 15:32:00 +0800</lastBuildDate>
    <item>
      <title>wcode v0.8：我开始把仓库当成一个 Engineering Digital Twin</title>
      <link>https://francisdu.com/blog/wcode-v0-8/</link>
      <pubDate>Sat, 19 Sep 2026 15:32:00 +0800</pubDate>
      <guid>https://francisdu.com/blog/wcode-v0-8/</guid>
      <description>&lt;p&gt;0.7 做完以后，wcode 已经能让 Agent 比较安全地读仓库、改文件、跑验证，也能把 Design State、Software Graph、Evidence 和 Reconciliation 留下来。&lt;/p&gt;
&lt;p&gt;但我自己用它时还有一个很明显的问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Agent 能操作这个仓库，不代表人能快速看懂这个仓库现在是什么状态。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很多时候我还是会回到 IDE：看目录、找调用方、翻测试、对照 Git Diff，再回 wcode 看验证。几套视图各自都对，但它们没有真正收成同一个工程模型。&lt;/p&gt;
&lt;p&gt;所以 0.8 我想做的不是“再加几个 MCP Tool”，而是把这些东西往一个方向收：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;把仓库当成一个可以观测、查询、回看，而且知道自己证据精度的 Engineering Digital Twin。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;现在最新版本已经是 &lt;strong&gt;v0.8.1&lt;/strong&gt;。0.8.0 把这个骨架搭起来，0.8.1 又把 Decision Plane 和 Jev 的边界收紧了一轮。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-intro-intelligence-stack.zh-CN.svg&#34; alt=&#34;wcode 的工程智能栈：从仓库事实、图关系到验证证据&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;code-graph-不再只是把节点画出来&#34;&gt;Code Graph 不再只是“把节点画出来”&lt;a class=&#34;heading-anchor&#34; href=&#34;#code-graph-%e4%b8%8d%e5%86%8d%e5%8f%aa%e6%98%af%e6%8a%8a%e8%8a%82%e7%82%b9%e7%94%bb%e5%87%ba%e6%9d%a5&#34; aria-label=&#34;章节链接：Code Graph 不再只是“把节点画出来”&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;我以前一直对“代码图谱”这件事有点警惕。&lt;/p&gt;
&lt;p&gt;最容易做的是把函数、文件、模块全画成一个大球。看起来信息很多，实际用的时候还是不知道：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个关系从哪里来的；&lt;/li&gt;
&lt;li&gt;是 Tree-sitter 看出来的，还是 LSP 确认的；&lt;/li&gt;
&lt;li&gt;是设计里声明的，还是 Runtime 真跑过；&lt;/li&gt;
&lt;li&gt;这个调用关系属于当前代码，还是旧 Snapshot；&lt;/li&gt;
&lt;li&gt;它和这次 Working Tree 改动到底有没有关系。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;0.8 里我把 Code Graph 放进了 &lt;strong&gt;Engineering Architecture&lt;/strong&gt;，而不是再加一个顶层页面。&lt;/p&gt;
&lt;p&gt;架构还是主视图。Code Graph 只是继续往下钻的一层。&lt;/p&gt;
&lt;p&gt;现在可以从一个符号看 callers、callees、references、dependencies、implementation ownership、tests、requirements，以及 verification / proof context。&lt;/p&gt;
&lt;p&gt;但我不允许它无限扩张。Calls、Impact、All Evidence 都有 depth、node、edge 的硬上限，UI 也按“上游 → 当前节点 → 下游”来排，不做无限节点球。&lt;/p&gt;
&lt;p&gt;更重要的是，每条关系都保留自己的 &lt;strong&gt;provenance&lt;/strong&gt; 和 &lt;strong&gt;precision&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Declared、Syntax、Semantic/LSP、Runtime、Deterministic、Heuristic 不会最后被压成一句“confidence: high”。&lt;/p&gt;
&lt;p&gt;我宁可界面告诉我“这条边只是 syntax 推断”，也不想让一个漂亮的图把不确定性藏掉。&lt;/p&gt;
&lt;h3 id=&#34;graph-history-也进来了&#34;&gt;Graph History 也进来了&lt;a class=&#34;heading-anchor&#34; href=&#34;#graph-history-%e4%b9%9f%e8%bf%9b%e6%9d%a5%e4%ba%86&#34; aria-label=&#34;章节链接：Graph History 也进来了&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;0.8 的 Code Graph 可以直接切历史 Snapshot。&lt;/p&gt;
&lt;p&gt;这个功能我自己很喜欢，因为它解决的不是“现在代码怎么连”，而是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这条关系以前是不是也存在？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;切换 Snapshot 后只是只读时间旅行，不会重新扫描仓库，也不会改当前状态。&lt;/p&gt;
&lt;p&gt;对 Agent 来说这能做 impact/context；对人来说它更像一个工程历史视图。&lt;/p&gt;
&lt;h2 id=&#34;observatory-终于没那么吵了&#34;&gt;Observatory 终于没那么吵了&lt;a class=&#34;heading-anchor&#34; href=&#34;#observatory-%e7%bb%88%e4%ba%8e%e6%b2%a1%e9%82%a3%e4%b9%88%e5%90%b5%e4%ba%86&#34; aria-label=&#34;章节链接：Observatory 终于没那么吵了&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;0.7 时代的 Observatory 有一个很烦的问题：浏览器为了拿新状态，可能连续触发比较重的 Snapshot。&lt;/p&gt;
&lt;p&gt;功能没错，但体感很差。&lt;/p&gt;
&lt;p&gt;0.8 改成每个 Workspace 同时最多只有一个后台重快照。已经有缓存就先给缓存，同时带上 Revision Stamp，明确告诉前端 cached、current、refreshing。&lt;/p&gt;
&lt;p&gt;浏览器自己只做轻量探测，不再 fan-out 一组重请求。&lt;/p&gt;
&lt;p&gt;我顺便把 UI 的层级也重新整理了一次。&lt;/p&gt;
&lt;p&gt;第一眼只看 Project Pulse 和状态；第二眼才看指标、关系、时间线；Evidence 和 Inspector 放到第三层。&lt;/p&gt;
&lt;p&gt;Stale、Unknown、Inconclusive、Failed、Unverified 也不能再长得像绿色 Passing Proof。&lt;/p&gt;
&lt;p&gt;这是个很小的规则，但对“工程控制面”很重要：&lt;strong&gt;UI 不能比底层证据更自信。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;我开始真的把它叫-engineering-digital-twin&#34;&gt;我开始真的把它叫 Engineering Digital Twin&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e6%88%91%e5%bc%80%e5%a7%8b%e7%9c%9f%e7%9a%84%e6%8a%8a%e5%ae%83%e5%8f%ab-engineering-digital-twin&#34; aria-label=&#34;章节链接：我开始真的把它叫 Engineering Digital Twin&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这个名字以前我其实不太敢用。&lt;/p&gt;
&lt;p&gt;如果只是把代码索引成图，我觉得叫 Digital Twin 有点虚。&lt;/p&gt;
&lt;p&gt;0.8 以后我觉得它开始接近这个词了，因为看到的不再只有 Source：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Design State
    ↓
Implementation ownership
    ↓
Syntax / Semantic / Runtime relations
    ↓
Working Tree changes
    ↓
Drift / Risk / Impact
    ↓
Verification / Evidence
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这些东西不是复制一份新的“项目数据库”出来。&lt;/p&gt;
&lt;p&gt;源码、Git、Design State 和 Evidence 仍然各自是事实来源。Digital Twin 只是把它们组织成一个可查询的只读工程视图。&lt;/p&gt;
&lt;p&gt;这点我刻意没有放松。否则最后很容易出现第二份 mutable project state，然后你开始不知道到底应该信代码，还是信“数字孪生”。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-intro-engineering-loop.zh-CN.svg&#34; alt=&#34;wcode 的工程闭环：Context、Graph、Change、Verification 与 Evidence&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;decision-plane-也在-08-里真正成形了&#34;&gt;Decision Plane 也在 0.8 里真正成形了&lt;a class=&#34;heading-anchor&#34; href=&#34;#decision-plane-%e4%b9%9f%e5%9c%a8-08-%e9%87%8c%e7%9c%9f%e6%ad%a3%e6%88%90%e5%bd%a2%e4%ba%86&#34; aria-label=&#34;章节链接：Decision Plane 也在 0.8 里真正成形了&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;另一个我花时间很多的东西是 &lt;strong&gt;Decision Plane&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Coding Agent 有很多判断其实没必要直接交给大模型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Context 够不够；&lt;/li&gt;
&lt;li&gt;要不要继续 Retrieval；&lt;/li&gt;
&lt;li&gt;跨文件关系是不是安全修改前的必要证据；&lt;/li&gt;
&lt;li&gt;是否应该增加 Verification；&lt;/li&gt;
&lt;li&gt;当前状态是不是应该 abstain。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;0.8 把这类判断收成了 provider-neutral 的结构化信号：Probability、Choice、Score。&lt;/p&gt;
&lt;p&gt;但这里最重要的不是“可以接一个小模型”。&lt;/p&gt;
&lt;p&gt;最重要的是 &lt;strong&gt;Decision Plane 没有拿到安全边界的最终权限&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Authorization、Workspace Boundary、SHA Precondition、Evidence、Risk-derived Verification、Human Approval 还是确定性的。&lt;/p&gt;
&lt;p&gt;Decision Plane 可以说“我建议多查一点”，但不能说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我有 0.93 confidence，所以这个 SHA 不用检查了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这种路我一开始就不想走。&lt;/p&gt;
&lt;h2 id=&#34;engineering-fitness-不再拿自己的-readiness-当答案&#34;&gt;Engineering Fitness 不再拿自己的 readiness 当答案&lt;a class=&#34;heading-anchor&#34; href=&#34;#engineering-fitness-%e4%b8%8d%e5%86%8d%e6%8b%bf%e8%87%aa%e5%b7%b1%e7%9a%84-readiness-%e5%bd%93%e7%ad%94%e6%a1%88&#34; aria-label=&#34;章节链接：Engineering Fitness 不再拿自己的 readiness 当答案&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Decision Plane 如果没有独立评测，很容易变成自己给自己打分。&lt;/p&gt;
&lt;p&gt;所以 0.8 的 Context Sufficiency 改成对照独立写的 &lt;strong&gt;Engineering Fitness Gold&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我关心的不只是“有没有找到文件”，而是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Required Identity 有没有找到；&lt;/li&gt;
&lt;li&gt;完整 Source Body 有没有交给 Agent；&lt;/li&gt;
&lt;li&gt;SHA 是不是新鲜；&lt;/li&gt;
&lt;li&gt;真要编辑时需要的 Edit Inputs 有没有齐。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;0.8.0 发布时那组 60-case model-free diagnostic 里，1K cold / warm 的 Required Identity Recall、Complete Body Recall、Fresh SHA Recall 都是 &lt;strong&gt;100%&lt;/strong&gt;；58 个可写 Eligible Case 里 &lt;strong&gt;58/58&lt;/strong&gt; 都拿到了完整 Edit Inputs。&lt;/p&gt;
&lt;p&gt;Decision baseline 的 Brier 是 &lt;strong&gt;0.018846&lt;/strong&gt;，False Stop 和 False Continue 都是 &lt;strong&gt;0&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我不会把这组数写成“wcode 已经解决 Context Engineering”。&lt;/p&gt;
&lt;p&gt;它只是一个比较有用的基线：以后我改 Retrieval、Ranking、Budget 或 Decision Plane 时，至少有一组不依赖主模型的东西可以告诉我是不是把基本能力改坏了。&lt;/p&gt;
&lt;h2 id=&#34;jev-在-081-里被我又收窄了一次&#34;&gt;Jev 在 0.8.1 里被我又收窄了一次&lt;a class=&#34;heading-anchor&#34; href=&#34;#jev-%e5%9c%a8-081-%e9%87%8c%e8%a2%ab%e6%88%91%e5%8f%88%e6%94%b6%e7%aa%84%e4%ba%86%e4%b8%80%e6%ac%a1&#34; aria-label=&#34;章节链接：Jev 在 0.8.1 里被我又收窄了一次&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;0.8.0 已经能让 Decision Plane 比较 baseline 和 candidate provider。&lt;/p&gt;
&lt;p&gt;到了 0.8.1，我把外部语义 Provider 的命名统一成了 &lt;strong&gt;Jev&lt;/strong&gt;，本地无模型层就叫 &lt;strong&gt;Decision Plane&lt;/strong&gt;，主模型继续叫 &lt;strong&gt;Reasoning Model&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;更重要的是，问题本身也重新写了一轮。&lt;/p&gt;
&lt;p&gt;比如我原来会问：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;semantic navigation 有没有帮助？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个问题太宽了。&lt;/p&gt;
&lt;p&gt;在 Coding Agent 里，看看更多关系几乎永远“有帮助”。于是 Provider 很容易一直建议继续查。&lt;/p&gt;
&lt;p&gt;0.8.1 的问题变成更窄的边界：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;semantic relationships 是不是安全修改前的必要证据？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Choice 也不再只有“继续/不继续”，而是把正反 criteria 写清楚，并加入 other_review。&lt;/p&gt;
&lt;p&gt;不完整、低集中度、边界不清楚的状态就 abstain，回去收集证据。&lt;/p&gt;
&lt;p&gt;当前 Agent Context 的 Jev question set 是 wcode.agent_context@3。&lt;/p&gt;
&lt;h3 id=&#34;jev-只能-increase-only&#34;&gt;Jev 只能 increase-only&lt;a class=&#34;heading-anchor&#34; href=&#34;#jev-%e5%8f%aa%e8%83%bd-increase-only&#34; aria-label=&#34;章节链接：Jev 只能 increase-only&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Jev 现在可以要求更多 Retrieval、Semantic Navigation、更多 Verification，或者继续 Reasoning。&lt;/p&gt;
&lt;p&gt;但不能减少 deterministic baseline 要求的工作。&lt;/p&gt;
&lt;p&gt;尤其是 edit_then_verify：只有 baseline 本来就允许同一动作时，Jev 才能同意；它自己不能把一个 Unknown 状态升级成“可以编辑”。&lt;/p&gt;
&lt;p&gt;而且 Jev advisory 如果会把 Agent Context 撑过预算，先丢的是 advisory，不是 Source、SHA、Test 或 Risk Evidence。&lt;/p&gt;
&lt;p&gt;这也是我现在比较满意的一点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;外部 Provider 挂掉，wcode 少一层建议；它不会少一层安全。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;shadow-ab-比换掉-baseline更适合我现在的阶段&#34;&gt;Shadow A/B 比“换掉 baseline”更适合我现在的阶段&lt;a class=&#34;heading-anchor&#34; href=&#34;#shadow-ab-%e6%af%94%e6%8d%a2%e6%8e%89-baseline%e6%9b%b4%e9%80%82%e5%90%88%e6%88%91%e7%8e%b0%e5%9c%a8%e7%9a%84%e9%98%b6%e6%ae%b5&#34; aria-label=&#34;章节链接：Shadow A/B 比“换掉 baseline”更适合我现在的阶段&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;0.8 没有直接让 Jev 接管 Decision Plane。&lt;/p&gt;
&lt;p&gt;同一个不可变 DecisionRequest 会同时给 baseline 和 candidate，然后记录 shared / missing signal、probability / score delta、Choice disagreement、shape mismatch 和 safety-policy violation。&lt;/p&gt;
&lt;p&gt;这更像 Shadow A/B。&lt;/p&gt;
&lt;p&gt;我先看它在哪些状态下和 baseline 不一样，再决定它有没有资格影响 Runtime。&lt;/p&gt;
&lt;p&gt;这种做法慢一点，但比“API 接通了 → 默认启用 → 看线上有没有出事”靠谱很多。&lt;/p&gt;
&lt;h2 id=&#34;仓库扫描也终于统一尊重-ignore&#34;&gt;仓库扫描也终于统一尊重 Ignore&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e4%bb%93%e5%ba%93%e6%89%ab%e6%8f%8f%e4%b9%9f%e7%bb%88%e4%ba%8e%e7%bb%9f%e4%b8%80%e5%b0%8a%e9%87%8d-ignore&#34; aria-label=&#34;章节链接：仓库扫描也终于统一尊重 Ignore&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这部分不太显眼，但实际体感提升很大。&lt;/p&gt;
&lt;p&gt;以前 Source Scan、Search、Index、Status、Subspace Discovery 各自有自己的遍历路径，很容易出现一条链路避开 target，另一条链路又进去。&lt;/p&gt;
&lt;p&gt;0.8 把这些统一到 Ignore-aware Walker。&lt;/p&gt;
&lt;p&gt;默认遵守 .gitignore、.ignore、Git info exclude、global exclude 和 protected paths。target、node_modules、cache、常见 build output 也会在 traversal 前就剪掉。&lt;/p&gt;
&lt;p&gt;但 explicit intent 还是优先：你明确指定一个 ignored path，Read/Search 仍然可以在边界内访问。&lt;/p&gt;
&lt;p&gt;我不想为了性能把“用户明确叫我读这个文件”也一起吞掉。&lt;/p&gt;
&lt;h2 id=&#34;tui-现在更像任务控制面&#34;&gt;TUI 现在更像任务控制面&lt;a class=&#34;heading-anchor&#34; href=&#34;#tui-%e7%8e%b0%e5%9c%a8%e6%9b%b4%e5%83%8f%e4%bb%bb%e5%8a%a1%e6%8e%a7%e5%88%b6%e9%9d%a2&#34; aria-label=&#34;章节链接：TUI 现在更像任务控制面&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;0.8 的 TUI 我也砍了一些东西。&lt;/p&gt;
&lt;p&gt;宽终端现在是 70/30：Workspace Activity 占主画布，Engineering / connection state 放右侧。&lt;/p&gt;
&lt;p&gt;右边只留四条主要状态：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ARCH
DRIFT
PROOF
MODEL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;中等和窄终端干脆不常驻 Engineering Pulse，让任务本身优先。&lt;/p&gt;
&lt;p&gt;我越来越觉得 TUI 的任务不是把所有指标都塞进去，而是回答三个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;现在 Agent 在干什么；&lt;/li&gt;
&lt;li&gt;有没有卡在权限/验证/运行时；&lt;/li&gt;
&lt;li&gt;我什么时候需要介入。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详细 Architecture 和 Proof 还是可以进 Engineering Console 看。&lt;/p&gt;
&lt;h2 id=&#34;081-还修了两个看起来正确的-ui-问题&#34;&gt;0.8.1 还修了两个“看起来正确”的 UI 问题&lt;a class=&#34;heading-anchor&#34; href=&#34;#081-%e8%bf%98%e4%bf%ae%e4%ba%86%e4%b8%a4%e4%b8%aa%e7%9c%8b%e8%b5%b7%e6%9d%a5%e6%ad%a3%e7%a1%ae%e7%9a%84-ui-%e9%97%ae%e9%a2%98&#34; aria-label=&#34;章节链接：0.8.1 还修了两个“看起来正确”的 UI 问题&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这两个问题很典型。&lt;/p&gt;
&lt;p&gt;Code Graph 发请求时有 query / mode / depth / snapshot。旧响应晚回来时，只看“请求成功”是不够的；它必须和当前四个语义参数全部一致，才能发布到 UI。&lt;/p&gt;
&lt;p&gt;Access 页面也类似。Workspace、Commands、Authorizations 三路状态要原子发布。只要其中一路 shape validation 失败，就整组保持 Unknown。&lt;/p&gt;
&lt;p&gt;否则最危险的不是页面报错，而是页面展示一个&lt;strong&gt;部分正确、看起来又很完整&lt;/strong&gt;的状态。&lt;/p&gt;
&lt;p&gt;这和我前面说的其实是同一件事：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;工程 UI 不能比证据更确定。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;08-没有改变我最早那条边界&#34;&gt;0.8 没有改变我最早那条边界&lt;a class=&#34;heading-anchor&#34; href=&#34;#08-%e6%b2%a1%e6%9c%89%e6%94%b9%e5%8f%98%e6%88%91%e6%9c%80%e6%97%a9%e9%82%a3%e6%9d%a1%e8%be%b9%e7%95%8c&#34; aria-label=&#34;章节链接：0.8 没有改变我最早那条边界&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;从 0.3 到 0.8，wcode 上层已经变了很多。&lt;/p&gt;
&lt;p&gt;但几条底层原则我没有准备改：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Workspace Root 仍然是边界；&lt;/li&gt;
&lt;li&gt;修改仍然绑定 SHA；&lt;/li&gt;
&lt;li&gt;Full Access 只能由 Operator 明确选择；&lt;/li&gt;
&lt;li&gt;Decision Plane 不能授权；&lt;/li&gt;
&lt;li&gt;Jev 不能降低 Verification；&lt;/li&gt;
&lt;li&gt;Cancellation 不等于 Rollback；&lt;/li&gt;
&lt;li&gt;Verification Evidence 必须绑定具体 Revision。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Engineering Digital Twin 也是只读层。它不会因为“图里看起来应该这样”就去改项目。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-intro-verification-mesh.zh-CN.svg&#34; alt=&#34;wcode 的验证网格：确定性检查、独立 Review 与证据绑定&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;这次版本跨度其实挺大&#34;&gt;这次版本跨度其实挺大&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e8%bf%99%e6%ac%a1%e7%89%88%e6%9c%ac%e8%b7%a8%e5%ba%a6%e5%85%b6%e5%ae%9e%e6%8c%ba%e5%a4%a7&#34; aria-label=&#34;章节链接：这次版本跨度其实挺大&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;从 v0.7.6 到 v0.8.0，Git Diff 跨了 &lt;strong&gt;135 个文件，约 +7,364 / -775 行&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我一开始也以为这会是一个“Code Graph + Observatory UI”的版本。&lt;/p&gt;
&lt;p&gt;写到后面才发现，真正牵动的是整条链：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Repository scan
    ↓
Context
    ↓
Graph / Digital Twin
    ↓
Decision Plane
    ↓
Edit boundary
    ↓
Verification
    ↓
Evidence
    ↓
Human observability
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以最后我把 0.8 的主题定成了 &lt;strong&gt;Engineering Digital Twin&lt;/strong&gt;，而不是 Code Graph。&lt;/p&gt;
&lt;p&gt;Code Graph 只是其中一个入口。&lt;/p&gt;
&lt;h2 id=&#34;现在是-081&#34;&gt;现在是 0.8.1&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e7%8e%b0%e5%9c%a8%e6%98%af-081&#34; aria-label=&#34;章节链接：现在是 0.8.1&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.8.0 是 9 月 19 日发布的 Engineering Digital Twin 版本；同一天我又发了 v0.8.1，主要把 Jev Decision Plane、命名和 WebUI state truthfulness 收紧。&lt;/p&gt;
&lt;p&gt;如果你只想看版本说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wcode.francis.run/zh/docs/releases/v0.8.0/&#34;&gt;v0.8.0 — Engineering Digital Twin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wcode.francis.run/zh/docs/releases/v0.8.1/&#34;&gt;v0.8.1 — Jev Decision Plane 加固&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果问我 0.8 最重要的变化是什么，我现在会说：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;以前 wcode 主要是在帮助 Agent 安全地操作仓库；0.8 开始，我希望 Agent 和人看到的是同一份、带证据来源和精度的工程状态。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这件事还远没做完，但方向终于比较清楚了。&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>wcode v0.6.2：我不再拿 SLOTS 当性能了</title>
      <link>https://francisdu.com/blog/wcode-v0-6-2/</link>
      <pubDate>Sat, 12 Sep 2026 05:32:00 +0800</pubDate>
      <guid>https://francisdu.com/blog/wcode-v0-6-2/</guid>
      <description>&lt;p&gt;前几天我一直盯着 wcode 的并发面板看。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SLOTS&lt;/code&gt; 32，&lt;code&gt;PEAK&lt;/code&gt; 看起来也不低，但实际跑起来还是有一种很奇怪的感觉：数字挺忙，任务不一定真快。&lt;/p&gt;
&lt;p&gt;我把执行链拆开看了一遍，问题就清楚了。&lt;/p&gt;
&lt;p&gt;外层 Tool Slot 只表示请求已经准入。CPU、文件 I/O、&lt;code&gt;cargo&lt;/code&gt;、&lt;code&gt;git&lt;/code&gt;、Language Server 还有各自的线程池或队列，外面 32 个槽位全亮，并不代表里面 32 份工作都在向前跑。&lt;/p&gt;
&lt;p&gt;0.6.2 先把这些资源分开计量和限制。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-observatory-full_hu_2e0fc54b6ad597b6.webp&#34; alt=&#34;wcode Project Observatory&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34; srcset=&#34;https://francisdu.com/img/wcode/wcode-observatory-full_hu_2e0fc54b6ad597b6.webp 960w, https://francisdu.com/img/wcode/wcode-observatory-full_hu_77a4ca195d4c7462.webp 1600w&#34; sizes=&#34;(max-width: 900px) calc(100vw - 32px), 900px&#34; width=&#34;1600&#34; height=&#34;5017&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;slotscpuio子进程是四件事&#34;&gt;SLOTS、CPU、I/O、子进程是四件事&lt;a class=&#34;heading-anchor&#34; href=&#34;#slotscpuio%e5%ad%90%e8%bf%9b%e7%a8%8b%e6%98%af%e5%9b%9b%e4%bb%b6%e4%ba%8b&#34; aria-label=&#34;章节链接：SLOTS、CPU、I/O、子进程是四件事&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;现在我更愿意把执行路径看成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Tool admission
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Foreground CPU budget
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bounded file I/O pool
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Child process / Git probe queues
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;它们有不同的瓶颈。&lt;/p&gt;
&lt;p&gt;前台 CPU 工作线程会取硬件并行度、8 个线程、内存推导上限和请求并行度的最小值。阻塞线程池上限提高到 64，是为了不让大量独立阻塞请求被隐藏的较小线程上限卡住。&lt;/p&gt;
&lt;p&gt;独立文件修改走共享、有界的 I/O Pool；固定形式的 Git 状态和差异检查走独立 Probe Queue，不再和重型编译器进程抢同一组名额。&lt;/p&gt;
&lt;p&gt;默认资源预算下，重型子进程仍然是很小的并发数。因为同时启动 20 个 &lt;code&gt;cargo&lt;/code&gt; 不会 magically 变快，只会把机器打爆。&lt;/p&gt;
&lt;h2 id=&#34;我专门撤回过一个看起来更并行的优化&#34;&gt;我专门撤回过一个“看起来更并行”的优化&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e6%88%91%e4%b8%93%e9%97%a8%e6%92%a4%e5%9b%9e%e8%bf%87%e4%b8%80%e4%b8%aa%e7%9c%8b%e8%b5%b7%e6%9d%a5%e6%9b%b4%e5%b9%b6%e8%a1%8c%e7%9a%84%e4%bc%98%e5%8c%96&#34; aria-label=&#34;章节链接：我专门撤回过一个“看起来更并行”的优化&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这轮有一件事我觉得挺重要：我试过把热读取也放进更宽的线程池，结果本地配对实验更慢。&lt;/p&gt;
&lt;p&gt;所以撤回了。&lt;/p&gt;
&lt;p&gt;做 Agent Runtime 很容易有一种冲动：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;线程更多 = 更快
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;队列更深 = 吞吐更高
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;并发数更大 = Agent 更强
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;配对结果不好看就撤回。0.6.2 后面的资源调整也基本按这个标准做：先把不同类型的工作隔开，别靠调大一个统一并发值解决所有问题。&lt;/p&gt;
&lt;h2 id=&#34;32-个命令排队时我还希望-read-能进去&#34;&gt;32 个命令排队时，我还希望 Read 能进去&lt;a class=&#34;heading-anchor&#34; href=&#34;#32-%e4%b8%aa%e5%91%bd%e4%bb%a4%e6%8e%92%e9%98%9f%e6%97%b6%e6%88%91%e8%bf%98%e5%b8%8c%e6%9c%9b-read-%e8%83%bd%e8%bf%9b%e5%8e%bb&#34; aria-label=&#34;章节链接：32 个命令排队时，我还希望 Read 能进去&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;如果所有 Tool Slot 都被执行进程占满，Agent 连 &lt;code&gt;read_file&lt;/code&gt;、状态查询这种轻操作都进不来，系统就会出现另一种死锁感。&lt;/p&gt;
&lt;p&gt;所以执行进程类工具在拿总 Tool Slot 前，还要先拿一层 Execution Admission。&lt;/p&gt;
&lt;p&gt;总量是 32 时，执行类请求最多占 28 个槽位，给非执行工具留四个受控余量。单槽位配置则保留一个可用名额，不会把自己完全饿死。&lt;/p&gt;
&lt;p&gt;它不保证固定延迟，但编译队列再长，&lt;code&gt;read_file&lt;/code&gt; 和状态查询至少还有机会进来。&lt;/p&gt;
&lt;h2 id=&#34;明确的错误位置不应该先全仓搜索&#34;&gt;明确的错误位置，不应该先全仓搜索&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e6%98%8e%e7%a1%ae%e7%9a%84%e9%94%99%e8%af%af%e4%bd%8d%e7%bd%ae%e4%b8%8d%e5%ba%94%e8%af%a5%e5%85%88%e5%85%a8%e4%bb%93%e6%90%9c%e7%b4%a2&#34; aria-label=&#34;章节链接：明确的错误位置，不应该先全仓搜索&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;性能不只在 Scheduler。&lt;/p&gt;
&lt;p&gt;我调真实任务时发现另一个很浪费的路径：模型已经拿到了这种信息：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;error[E0308] at src/runtime/harness/context_budget.rs:33:9
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;结果 &lt;code&gt;agent_context&lt;/code&gt; 还先做一遍广域符号检索，再回来读这个明确位置。&lt;/p&gt;
&lt;p&gt;这顺序反了。&lt;/p&gt;
&lt;p&gt;现在带文件和行号的诊断会先经过 Workspace 保护解析，然后直接保留对应源码原文、行范围和 SHA 编辑前置条件。简单位置查询可以暂缓 Repo Graph 扩展；调用方、Impact、架构或显式 Scope 查询仍然走深入路径。&lt;/p&gt;
&lt;p&gt;缺失位置也不会先把一堆无关文件索引起来再告诉我“没找到”。&lt;/p&gt;
&lt;p&gt;这类任务现在先吃掉已有的精确位置，只有问题真的需要跨文件关系时才继续扩图。&lt;/p&gt;
&lt;h2 id=&#34;同一个冷索引也不应该被重复建-10-次&#34;&gt;同一个冷索引也不应该被重复建 10 次&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e5%90%8c%e4%b8%80%e4%b8%aa%e5%86%b7%e7%b4%a2%e5%bc%95%e4%b9%9f%e4%b8%8d%e5%ba%94%e8%af%a5%e8%a2%ab%e9%87%8d%e5%a4%8d%e5%bb%ba-10-%e6%ac%a1&#34; aria-label=&#34;章节链接：同一个冷索引也不应该被重复建 10 次&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;并发 Agent 很容易同时问同一个文件。&lt;/p&gt;
&lt;p&gt;以前多个冷查询可能一起发现“没有索引”，然后各自开始建。&lt;/p&gt;
&lt;p&gt;现在同一 Workspace、同一文件的冷查询会共享正在进行的索引构建。不同文件仍然可以独立执行；失效和版本变化会阻止旧构建结果晚到后重新污染缓存。&lt;/p&gt;
&lt;p&gt;这里没有做增量 Tree-sitter，也没有引入全仓快照，只是把同一份冷索引的重复构建合掉。&lt;/p&gt;
&lt;h2 id=&#34;symbol_context-开始对自己返回的版本负责&#34;&gt;&lt;code&gt;symbol_context&lt;/code&gt; 开始对自己返回的版本负责&lt;a class=&#34;heading-anchor&#34; href=&#34;#symbol_context-%e5%bc%80%e5%a7%8b%e5%af%b9%e8%87%aa%e5%b7%b1%e8%bf%94%e5%9b%9e%e7%9a%84%e7%89%88%e6%9c%ac%e8%b4%9f%e8%b4%a3&#34; aria-label=&#34;章节链接：symbol_context 开始对自己返回的版本负责&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;另一个一致性问题是：索引说 Symbol 在 A，但真正读正文时文件已经变了。&lt;/p&gt;
&lt;p&gt;如果这时还把旧签名和新正文拼成一个结果，Agent 会拿到一个内部自相矛盾的 Context。&lt;/p&gt;
&lt;p&gt;现在 &lt;code&gt;symbol_context&lt;/code&gt; 会核对符号信息和正文是不是同一文件版本。发现旧索引最多重新获取一次；文件持续变化、拿不到稳定版本时，就明确失败。&lt;/p&gt;
&lt;p&gt;我宁愿返回“现在无法稳定读取”，也不想返回一个看起来完整的 Frankenstein Context。&lt;/p&gt;
&lt;h2 id=&#34;验证计划不能静默只跑前八项&#34;&gt;验证计划不能静默只跑前八项&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e9%aa%8c%e8%af%81%e8%ae%a1%e5%88%92%e4%b8%8d%e8%83%bd%e9%9d%99%e9%bb%98%e5%8f%aa%e8%b7%91%e5%89%8d%e5%85%ab%e9%a1%b9&#34; aria-label=&#34;章节链接：验证计划不能静默只跑前八项&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;0.6.2 还修了一个更严重的问题。&lt;/p&gt;
&lt;p&gt;混合语言仓库里，完整验证可能推导出十几项检查。旧路径有一处会静默只取前八项。&lt;/p&gt;
&lt;p&gt;这类优化最危险的地方不是少跑了几个命令，而是上层可能还把已经执行的前缀描述成“完整验证”。&lt;/p&gt;
&lt;p&gt;现在先构造完整计划，整体上限是 32。超限就&lt;strong&gt;在派发前失败&lt;/strong&gt;，明确告诉调用者没有执行检查，而不是偷偷截断。&lt;/p&gt;
&lt;p&gt;验证历史也会在一次请求里共享代码 Revision 和 Evidence Snapshot，减少重复扫描；结果要同时匹配 Code 和 Design State 才能展示为当前有效。&lt;/p&gt;
&lt;p&gt;窄范围检查不能把宽范围失败抹掉，时间戳冲突按失败关闭。Evidence 缺失或扫描截断，也不能被解释成通过。&lt;/p&gt;
&lt;h2 id=&#34;verify_project-可以断线以后再查&#34;&gt;&lt;code&gt;verify_project&lt;/code&gt; 可以断线以后再查&lt;a class=&#34;heading-anchor&#34; href=&#34;#verify_project-%e5%8f%af%e4%bb%a5%e6%96%ad%e7%ba%bf%e4%bb%a5%e5%90%8e%e5%86%8d%e6%9f%a5&#34; aria-label=&#34;章节链接：verify_project 可以断线以后再查&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;项目验证现在还复用了 MCP Tasks 扩展。&lt;/p&gt;
&lt;p&gt;客户端支持 Tasks 时，服务端可以先持久化任务并返回 &lt;code&gt;taskId&lt;/code&gt;，验证继续由 Runtime 管理。客户端断线后，可以拿同一个 ID 查询状态。&lt;/p&gt;
&lt;p&gt;这里我刻意没有加一个模型可见的 &lt;code&gt;async=true&lt;/code&gt; 参数，也没有把断线等同于自动重试。&lt;/p&gt;
&lt;p&gt;因为对带副作用的系统来说，最危险的一句话就是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;没收到响应，那再执行一遍吧。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;完成状态只表示底层工具返回了结果，不等于检查通过；调用者还必须读真正的 &lt;code&gt;passed&lt;/code&gt; / error 状态。&lt;/p&gt;
&lt;h2 id=&#34;配置终于开始收敛&#34;&gt;配置终于开始收敛&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e9%85%8d%e7%bd%ae%e7%bb%88%e4%ba%8e%e5%bc%80%e5%a7%8b%e6%94%b6%e6%95%9b&#34; aria-label=&#34;章节链接：配置终于开始收敛&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;wcode 可调参数越来越多以后，另一个问题也很明显：高级参数是给调试和特殊机器用的，不应该逼所有人启动时手写一排数字。&lt;/p&gt;
&lt;p&gt;所以现在有三档常用性能配置：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;balanced
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fast
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;light
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也可以先预览：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wcode setup --performance fast --dry-run
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wcode --show-config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;真的执行 Setup 才会保存审核过的启动选项。&lt;/p&gt;
&lt;p&gt;同时新增了：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wcode help-all
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wcode help-all setup
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wcode help-all --json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;它直接从真实 CLI Parser 生成完整命令和参数目录，包括隐藏高级选项、短参数、别名、默认值和枚举值。&lt;/p&gt;
&lt;p&gt;普通 &lt;code&gt;--help&lt;/code&gt; 继续保持短。我不想为了“可发现性”把日常帮助页重新塞成说明书。&lt;/p&gt;
&lt;h2 id=&#34;webui-首屏也一起收了&#34;&gt;WebUI 首屏也一起收了&lt;a class=&#34;heading-anchor&#34; href=&#34;#webui-%e9%a6%96%e5%b1%8f%e4%b9%9f%e4%b8%80%e8%b5%b7%e6%94%b6%e4%ba%86&#34; aria-label=&#34;章节链接：WebUI 首屏也一起收了&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Observatory 这轮主要改首屏信息层级。&lt;/p&gt;
&lt;p&gt;现在执行活动、待批准请求、工作树变更、当前有效验证结果分开显示。Architecture 入口改成可搜索组件卡片和详情 Inspector，Design / Implementation / Overlay 图仍然保留，但不再要求用户先读一张很大的图才能知道项目现在发生了什么。&lt;/p&gt;
&lt;p&gt;活动刷新也和慢项目刷新拆开。页面隐藏时停止轮询；共享进程资源和当前项目任务分开标记；“没有采样”不再画成“0”。&lt;/p&gt;
&lt;p&gt;我主要想避免一件事：没有数据时别画成一个看起来很健康的数字。&lt;/p&gt;
&lt;h2 id=&#34;做完以后我给自己留了几条检查项&#34;&gt;做完以后，我给自己留了几条检查项&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e5%81%9a%e5%ae%8c%e4%bb%a5%e5%90%8e%e6%88%91%e7%bb%99%e8%87%aa%e5%b7%b1%e7%95%99%e4%ba%86%e5%87%a0%e6%9d%a1%e6%a3%80%e6%9f%a5%e9%a1%b9&#34; aria-label=&#34;章节链接：做完以后，我给自己留了几条检查项&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;我最后给自己留下几条明确的检查项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slot 数不等于吞吐；&lt;/li&gt;
&lt;li&gt;拿到文件和行号，先读明确位置；&lt;/li&gt;
&lt;li&gt;Verification mapped 和 executed 分开；&lt;/li&gt;
&lt;li&gt;Task completed 和 checks passed 分开；&lt;/li&gt;
&lt;li&gt;断线不自动重放；&lt;/li&gt;
&lt;li&gt;没有采样就显示 unknown。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;0.6.2 没有一个单独的大功能，更多是在把这些边界钉死。对我来说，这比再加一批 Tool 更实际。&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>wcode v0.6.1：`parallel_tools` 不再按层等</title>
      <link>https://francisdu.com/blog/wcode-v0-6-1/</link>
      <pubDate>Sat, 12 Sep 2026 05:31:00 +0800</pubDate>
      <guid>https://francisdu.com/blog/wcode-v0-6-1/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://francisdu.com/blog/wcode-v0-6/&#34;&gt;v0.6&lt;/a&gt; 开始在 &lt;code&gt;agent_context&lt;/code&gt; 里标出可以并行的工作。接着我去看 Runtime 本身，发现 &lt;code&gt;parallel_tools&lt;/code&gt; 虽然已经有依赖图，执行时还保留着按层推进的做法。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A ─→ C
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;B ─────────→ D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;假设 A 100ms 完成，B 要 5s，C 只依赖 A。&lt;/p&gt;
&lt;p&gt;按“层”执行时，很容易变成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;第一层：A + B
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ↓ 等两者都结束
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;第二层：C + D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;C 明明在 100ms 时已经 Ready，却因为一个和自己无关的 B，被迫多等几秒。&lt;/p&gt;
&lt;p&gt;所以 v0.6.1 我把调度器改成了 completion-driven。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-tui_hu_13e59e78ee0ce797.webp&#34; alt=&#34;wcode TUI&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34; srcset=&#34;https://francisdu.com/img/wcode/wcode-tui_hu_13e59e78ee0ce797.webp 960w, https://francisdu.com/img/wcode/wcode-tui_hu_6437a17a51f06ca3.webp 1800w&#34; sizes=&#34;(max-width: 900px) calc(100vw - 32px), 900px&#34; width=&#34;3420&#34; height=&#34;2146&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;ready-的任务不应该等同层慢分支&#34;&gt;Ready 的任务不应该等同层慢分支&lt;a class=&#34;heading-anchor&#34; href=&#34;#ready-%e7%9a%84%e4%bb%bb%e5%8a%a1%e4%b8%8d%e5%ba%94%e8%af%a5%e7%ad%89%e5%90%8c%e5%b1%82%e6%85%a2%e5%88%86%e6%94%af&#34; aria-label=&#34;章节链接：Ready 的任务不应该等同层慢分支&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;现在 Scheduler 只看一个问题：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这个任务自己的前置依赖是不是已经完成？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;满足就进入 Ready Queue。&lt;/p&gt;
&lt;p&gt;实际任务图通常不整齐。一个慢测试、一个大文件读取、一个外部命令，不该顺手把无关分支也拖住。&lt;/p&gt;
&lt;h2 id=&#34;失败也只应该污染依赖它的分支&#34;&gt;失败也只应该污染依赖它的分支&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e5%a4%b1%e8%b4%a5%e4%b9%9f%e5%8f%aa%e5%ba%94%e8%af%a5%e6%b1%a1%e6%9f%93%e4%be%9d%e8%b5%96%e5%ae%83%e7%9a%84%e5%88%86%e6%94%af&#34; aria-label=&#34;章节链接：失败也只应该污染依赖它的分支&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;同样的原则也用在失败上。&lt;/p&gt;
&lt;p&gt;如果：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A → C
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;B → D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A 失败，那么 C 应该被 Skip，因为它的前置不成立；但 B 和 D 不应该跟着一起失败。&lt;/p&gt;
&lt;p&gt;所以运行时会区分依赖失败导致的 Skip、当前任务自己的运行失败，以及完全独立、仍然可以继续的分支。&lt;/p&gt;
&lt;p&gt;这对批量读取、搜索、验证尤其重要。Agent 不应该因为一个不存在的可选文件，就失去其他已经能确定的结果。&lt;/p&gt;
&lt;h2 id=&#34;partial-不能假装-complete&#34;&gt;Partial 不能假装 Complete&lt;a class=&#34;heading-anchor&#34; href=&#34;#partial-%e4%b8%8d%e8%83%bd%e5%81%87%e8%a3%85-complete&#34; aria-label=&#34;章节链接：Partial 不能假装 Complete&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这轮我把批处理结果的语义也重新收紧了。&lt;/p&gt;
&lt;p&gt;批量读、创建、编辑、移动会明确报告：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;complete
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;partial
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;failed
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;并保留逐项结果。&lt;/p&gt;
&lt;p&gt;如果一个批次只完成了一部分，MCP Result 会保守地带错误标记，依赖整个批次的后续任务不能把它当作完整输入。独立分支仍然继续。&lt;/p&gt;
&lt;p&gt;重试也不应该重放整个批次。先核对状态，只重试失败项。这对写操作尤其重要，因为“请求失败”不等于“所有副作用都没发生”。&lt;/p&gt;
&lt;h2 id=&#34;并行写入最怕错误合并&#34;&gt;并行写入最怕错误合并&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e5%b9%b6%e8%a1%8c%e5%86%99%e5%85%a5%e6%9c%80%e6%80%95%e9%94%99%e8%af%af%e5%90%88%e5%b9%b6&#34; aria-label=&#34;章节链接：并行写入最怕错误合并&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;为了减少 Tool Call，wcode 会在安全条件满足时合并部分文件编辑。&lt;/p&gt;
&lt;p&gt;这里我宁愿少合并一点。&lt;/p&gt;
&lt;p&gt;同一个文件、同一个 SHA 的 Edit，如果中间隔着一个依赖 Read、Move 或其他会改变语义的操作，就不能跨过去合并。否则 Scheduler 会把原本有先后关系的工作偷偷变成一个事务。&lt;/p&gt;
&lt;p&gt;合并前也会检查既有的 128 项编辑上限，不能因为优化路径就绕过原来的安全边界。&lt;/p&gt;
&lt;p&gt;如果一次优化改掉了原本的先后关系，那就已经不是调度优化了。&lt;/p&gt;
&lt;h2 id=&#34;cancel-也必须真的往下传&#34;&gt;Cancel 也必须真的往下传&lt;a class=&#34;heading-anchor&#34; href=&#34;#cancel-%e4%b9%9f%e5%bf%85%e9%a1%bb%e7%9c%9f%e7%9a%84%e5%be%80%e4%b8%8b%e4%bc%a0&#34; aria-label=&#34;章节链接：Cancel 也必须真的往下传&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;异步系统里还有一个很烦的问题：外层任务取消了，不代表里面已经排队的工作自动消失。&lt;/p&gt;
&lt;p&gt;如果父请求断开，而子任务还在队列里，最糟的情况是用户以为“已经取消”，几秒后某个写操作才突然开始。&lt;/p&gt;
&lt;p&gt;v0.6.1 把取消传播继续往下压：父任务取消会取消仍在排队的子任务；持久 MCP Task 被取消或 TTL 过期，也会取消它拥有的执行任务。&lt;/p&gt;
&lt;p&gt;已经开始的阻塞文件操作不会假装回滚。这条边界也要说清楚。&lt;/p&gt;
&lt;h2 id=&#34;并发许可要跟真实工作走&#34;&gt;并发许可要跟真实工作走&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e5%b9%b6%e5%8f%91%e8%ae%b8%e5%8f%af%e8%a6%81%e8%b7%9f%e7%9c%9f%e5%ae%9e%e5%b7%a5%e4%bd%9c%e8%b5%b0&#34; aria-label=&#34;章节链接：并发许可要跟真实工作走&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;以前还有一种容易让面板数据看起来比实际更漂亮的情况：外层 Future 被取消以后，如果并发许可提前释放，但底层阻塞工作其实还在跑，就会出现“系统看起来有空位，实际上旧工作没结束”。&lt;/p&gt;
&lt;p&gt;现在已经启动的阻塞工作会继续持有对应许可，直到结束或异常退出。排队工作取消则会释放预留。&lt;/p&gt;
&lt;p&gt;我更愿意让数字难看一点，也不想让 Scheduler 对自己的真实资源状态撒谎。&lt;/p&gt;
&lt;h2 id=&#34;context-也继续往目标优先收紧&#34;&gt;Context 也继续往目标优先收紧&lt;a class=&#34;heading-anchor&#34; href=&#34;#context-%e4%b9%9f%e7%bb%a7%e7%bb%ad%e5%be%80%e7%9b%ae%e6%a0%87%e4%bc%98%e5%85%88%e6%94%b6%e7%b4%a7&#34; aria-label=&#34;章节链接：Context 也继续往目标优先收紧&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;顺手还改了一轮 &lt;code&gt;agent_context&lt;/code&gt; 的候选排序：精确定义优先于相似辅助函数；直接目标文件优先于按字母排在前面的 Design 映射；并行建议开始结合当前 Scope、活动 Worklist Lane 和运行时并发上限，而不是固定最多四路。&lt;/p&gt;
&lt;p&gt;Lane 数只用来给 Agent 提示，并不能证明两件事真的独立。最后仍然由真实资源和依赖决定能不能一起跑。&lt;/p&gt;
&lt;h2 id=&#34;observatory-不再把有映射当已验证&#34;&gt;Observatory 不再把“有映射”当“已验证”&lt;a class=&#34;heading-anchor&#34; href=&#34;#observatory-%e4%b8%8d%e5%86%8d%e6%8a%8a%e6%9c%89%e6%98%a0%e5%b0%84%e5%bd%93%e5%b7%b2%e9%aa%8c%e8%af%81&#34; aria-label=&#34;章节链接：Observatory 不再把“有映射”当“已验证”&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Project Observatory 这轮还修了一个我很在意的表达问题。&lt;/p&gt;
&lt;p&gt;以前“某个 Requirement 有 Verification 映射”和“这个 Revision 上真的执行并通过了验证”在视觉上太容易靠近。&lt;/p&gt;
&lt;p&gt;现在会明确区分：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;verification mapped
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;executed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;passed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fresh proof
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;因为有测试文件，不等于测试跑过；测试跑过，也不等于它属于现在这份代码。&lt;/p&gt;
&lt;h2 id=&#34;这版主要把无意义等待拿掉&#34;&gt;这版主要把无意义等待拿掉&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e8%bf%99%e7%89%88%e4%b8%bb%e8%a6%81%e6%8a%8a%e6%97%a0%e6%84%8f%e4%b9%89%e7%ad%89%e5%be%85%e6%8b%bf%e6%8e%89&#34; aria-label=&#34;章节链接：这版主要把无意义等待拿掉&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.6.1 基本都在修执行语义：Ready 就进队列，失败只截断依赖分支，Partial 明确报告 Partial，Cancel 继续往子任务传，许可跟着真实工作释放。&lt;/p&gt;
&lt;p&gt;它不会把本来串行的任务凭空变快，但长任务里少掉几次无关等待，体感很明显。&lt;/p&gt;
&lt;p&gt;再往后到 v0.6.2，我又继续拆了一个误区：&lt;strong&gt;外层 &lt;code&gt;SLOTS&lt;/code&gt; 很高，不代表真实吞吐就高。&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>wcode v0.6：哪些工具调用可以一起跑</title>
      <link>https://francisdu.com/blog/wcode-v0-6/</link>
      <pubDate>Sat, 12 Sep 2026 05:30:00 +0800</pubDate>
      <guid>https://francisdu.com/blog/wcode-v0-6/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://francisdu.com/blog/wcode-v0-5/&#34;&gt;v0.5&lt;/a&gt; 做完 Warm LSP Runtime 以后，我原本打算继续补 Semantic。&lt;/p&gt;
&lt;p&gt;实际拿 wcode 连续写了几轮代码，先暴露出来的却是执行节奏：模型已经知道几件事互不依赖，还是经常按顺序一个个调用工具。&lt;/p&gt;
&lt;p&gt;例如一个普通修改，前面经常同时存在几条工作：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;读目标文件
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;查相关测试
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;看项目约束
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;确认调用方
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;检查工作树
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这些动作很多没有依赖关系。如果 Prompt 只写一句“可以并行”，模型仍然很容易串着做。&lt;/p&gt;
&lt;p&gt;v0.6 就从这里开始改。我想让 Harness 少给模型一层猜测：当前任务有哪些入口，哪些可以一起做，哪些必须等前一步完成。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-architecture_hu_92a8fd07f12ae64a.webp&#34; alt=&#34;wcode Architecture&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34; srcset=&#34;https://francisdu.com/img/wcode/wcode-architecture_hu_92a8fd07f12ae64a.webp 960w, https://francisdu.com/img/wcode/wcode-architecture_hu_3f3f08e508cea449.webp 1800w&#34; sizes=&#34;(max-width: 900px) calc(100vw - 32px), 900px&#34; width=&#34;3232&#34; height=&#34;1932&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;agent_context-不再只是一包上下文&#34;&gt;&lt;code&gt;agent_context&lt;/code&gt; 不再只是一包上下文&lt;a class=&#34;heading-anchor&#34; href=&#34;#agent_context-%e4%b8%8d%e5%86%8d%e5%8f%aa%e6%98%af%e4%b8%80%e5%8c%85%e4%b8%8a%e4%b8%8b%e6%96%87&#34; aria-label=&#34;章节链接：agent_context 不再只是一包上下文&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;最早的 &lt;code&gt;agent_context&lt;/code&gt; 主要解决 Context 成本。&lt;/p&gt;
&lt;p&gt;它把 Design State、Repo Map、目标源码、SHA、验证入口和项目约束压进一个有界包里，让模型不用每次从根目录重新理解一遍。&lt;/p&gt;
&lt;p&gt;到了 v0.6，我给这份 Context 又加了一层执行信息：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;你现在应该做什么？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;哪些动作可以一起做？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;哪些动作有真实依赖？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;哪些文件已经是可编辑目标？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;哪些 Semantic Provider 已经可用？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这次修改应该控制在多大范围？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所以 Context 里开始明确带 Minimal-change Strategy、Complexity Budget、Active Worklist、Hot Source、Semantic Provider Readiness、绑定当前 Revision 的文件 SHA、候选 Dependency Lane，以及推荐并发数和立即并行的执行指引。&lt;/p&gt;
&lt;p&gt;现在这份 Context 除了描述仓库，也会把这次任务已经确定的执行入口一起带出来。&lt;/p&gt;
&lt;h2 id=&#34;parallel-first-不等于把槽位占满&#34;&gt;Parallel-first 不等于“把槽位占满”&lt;a class=&#34;heading-anchor&#34; href=&#34;#parallel-first-%e4%b8%8d%e7%ad%89%e4%ba%8e%e6%8a%8a%e6%a7%bd%e4%bd%8d%e5%8d%a0%e6%bb%a1&#34; aria-label=&#34;章节链接：Parallel-first 不等于“把槽位占满”&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;并行最容易做成一个漂亮但没什么用的数字。多发几个 Tool Call 很简单，麻烦的是先确认它们之间到底有没有依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;独立 Discovery     ─┐
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;独立 Read          ─┼─→ 同时开始
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;独立 Review        ─┤
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;独立 Check         ─┘
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;需要前置结果的 Edit ───→ 等依赖满足再开始
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;同一文件冲突写入     ───→ 串行
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;授权后才能执行的命令 ───→ 等批准
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;v0.6 的规则很直接：先看依赖，再决定哪些调用一起发。&lt;/p&gt;
&lt;p&gt;v0.6 的 Skill 和 Agent 工作流也开始明确要求：Host 支持并行调用时，应该尽早把独立的 Discovery、Read、Review、Check，以及不重叠 Edit 发出去。&lt;/p&gt;
&lt;h2 id=&#34;我不想让模型自己猜仓库结构&#34;&gt;我不想让模型自己猜仓库结构&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e6%88%91%e4%b8%8d%e6%83%b3%e8%ae%a9%e6%a8%a1%e5%9e%8b%e8%87%aa%e5%b7%b1%e7%8c%9c%e4%bb%93%e5%ba%93%e7%bb%93%e6%9e%84&#34; aria-label=&#34;章节链接：我不想让模型自己猜仓库结构&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;以前 Agent 虽然拿到了很多能力，但仍然可能自己脑补：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这个项目大概是 Rust + Web？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这个目录看起来可能是 UI？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这里应该跑 cargo test？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;那个 Language Server 应该已经能用了？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这种猜测单次看没什么，长任务里会不断累积。&lt;/p&gt;
&lt;p&gt;所以 Task-ready Context 会更主动地把已经确定的东西摆出来。目标文件是谁，就把目标文件和 SHA 放前面；当前 Scope 是什么，就把相关源码和 Worklist Lane 放前面；Semantic Provider 还没准备好，就明确说没准备好。&lt;/p&gt;
&lt;p&gt;我在 &lt;a href=&#34;https://francisdu.com/blog/wcode-software-graph/&#34;&gt;Software Graph&lt;/a&gt; 那篇里写过一次：Tree-sitter、LSP、Runtime 是不同精度的事实。&lt;/p&gt;
&lt;p&gt;执行层也照这个规则。Provider 没准备好就明确标出来，不用一个模糊状态让模型自己猜。&lt;/p&gt;
&lt;h2 id=&#34;lsp-也开始按真实安全边界工作&#34;&gt;LSP 也开始按真实安全边界工作&lt;a class=&#34;heading-anchor&#34; href=&#34;#lsp-%e4%b9%9f%e5%bc%80%e5%a7%8b%e6%8c%89%e7%9c%9f%e5%ae%9e%e5%ae%89%e5%85%a8%e8%be%b9%e7%95%8c%e5%b7%a5%e4%bd%9c&#34; aria-label=&#34;章节链接：LSP 也开始按真实安全边界工作&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.5 把 LSP 做成了 Warm Semantic Runtime。&lt;/p&gt;
&lt;p&gt;v0.6 又补了一层：Server Discovery、Binary Identity、Bounded Warm Session、Source Revision Sync 和 Safety Profile。&lt;/p&gt;
&lt;p&gt;Language Server 不是纯文本查询器。它可能读取项目配置、调用构建系统、加载插件，甚至间接触发仓库里的代码。&lt;/p&gt;
&lt;p&gt;所以“机器上装了 rust-analyzer”不等于“Agent 可以无条件启动 rust-analyzer”。如果某个 Server 没有明确的 Automatic Safety Profile，wcode 会 Fail Closed，然后进入精确授权流程。&lt;/p&gt;
&lt;h2 id=&#34;命令授权从允许禁止变成精确指纹&#34;&gt;命令授权从“允许/禁止”变成精确指纹&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e5%91%bd%e4%bb%a4%e6%8e%88%e6%9d%83%e4%bb%8e%e5%85%81%e8%ae%b8%e7%a6%81%e6%ad%a2%e5%8f%98%e6%88%90%e7%b2%be%e7%a1%ae%e6%8c%87%e7%ba%b9&#34; aria-label=&#34;章节链接：命令授权从“允许/禁止”变成精确指纹&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.6 还有一块变化，我自己用起来很明显：本地探查命令少打断了，但真正可能执行仓库代码或者产生副作用的命令，也不再只有“永久拒绝”这一条路。&lt;/p&gt;
&lt;p&gt;只要没有撞上硬安全边界，就可以生成一次精确的 &lt;code&gt;RiskyExecution&lt;/code&gt; 请求。&lt;/p&gt;
&lt;p&gt;批准绑定的是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Program
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Arguments
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Working Directory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我批准一次 &lt;code&gt;cargo test --locked&lt;/code&gt;，不代表顺便批准 &lt;code&gt;cargo publish&lt;/code&gt;，更不代表给 Agent 无限 Full Access。&lt;/p&gt;
&lt;p&gt;Shell、Workspace Escape、Protected Path、凭据或配置重定向、Host-wide Tool Mutation、Package Publication / Ownership，以及明显破坏性的基础设施操作，仍然是硬边界。&lt;/p&gt;
&lt;p&gt;我最后留下了一段很实用的中间地带：动作本身允许，但这一次要执行的 Workspace、Program、Arguments 和 Working Directory 必须让我看清楚再批。&lt;/p&gt;
&lt;h2 id=&#34;这版主要在收执行摩擦&#34;&gt;这版主要在收执行摩擦&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e8%bf%99%e7%89%88%e4%b8%bb%e8%a6%81%e5%9c%a8%e6%94%b6%e6%89%a7%e8%a1%8c%e6%91%a9%e6%93%a6&#34; aria-label=&#34;章节链接：这版主要在收执行摩擦&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;parallel&lt;/code&gt;、&lt;code&gt;context&lt;/code&gt;、&lt;code&gt;LSP&lt;/code&gt;、&lt;code&gt;authorization&lt;/code&gt; 这些改动看起来分散，实际都来自我自己使用时反复碰到的几类浪费：模型重复确认已经知道的事实、明明可以并行却串着查、语义服务状态不清楚、命令到了最后一步才发现权限不够。&lt;/p&gt;
&lt;p&gt;v0.6 做的就是把这些信息提前放进 Runtime 能确定的位置，尽量少让模型靠 Prompt 猜。&lt;/p&gt;
&lt;p&gt;我也不会给 v0.6 编一个“通用提速百分比”。真实收益取决于任务图、仓库、Host 是否支持并行调用，以及 Semantic Session 是否已经热起来。&lt;/p&gt;
&lt;p&gt;后面的 v0.6.1，我又继续把 &lt;code&gt;parallel_tools&lt;/code&gt; 调度器改了一轮。那次处理的是另一个更底层的问题：&lt;strong&gt;并行任务不应该因为同一层里有一个慢分支，就集体等它。&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>wcode v0.5：LSP 不再每次现启</title>
      <link>https://francisdu.com/blog/wcode-v0-5/</link>
      <pubDate>Sun, 30 Aug 2026 17:30:00 +0800</pubDate>
      <guid>https://francisdu.com/blog/wcode-v0-5/</guid>
      <description>&lt;p&gt;v0.4 做完以后，我以为 wcode 写代码这条主链已经比较顺了。&lt;/p&gt;
&lt;p&gt;那一版主要解决 Context 成本：&lt;code&gt;agent_context&lt;/code&gt; 变成 Coding Entry，Repo Map 有了 Cache 和 Scope，简单任务不需要每次把整个项目重新理解一遍。&lt;/p&gt;
&lt;p&gt;但真的继续拿它写代码，很快又遇到另一个问题。&lt;/p&gt;
&lt;p&gt;不是“找不到函数”。&lt;/p&gt;
&lt;p&gt;Tree-sitter 和 Search 对定位其实已经很好用了。&lt;/p&gt;
&lt;p&gt;真正麻烦的是这种问题：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;谁在调用这个函数？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这个 Trait 到底有哪些实现？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;改这个 Symbol 会影响哪些跨文件 Reference？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这个调用关系是同名文本，还是类型系统真正解析出来的？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这种时候，grep 能找到很多东西，但不一定完整；Tree-sitter 能告诉我语法结构，但它也不应该假装自己知道类型系统。&lt;/p&gt;
&lt;p&gt;所以 v0.5 没继续堆零散的 LSP API，我直接把 Language Server 的生命周期重新做了一遍，让它可以受限地常驻和复用。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-architecture_hu_92a8fd07f12ae64a.webp&#34; alt=&#34;wcode Architecture&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34; srcset=&#34;https://francisdu.com/img/wcode/wcode-architecture_hu_92a8fd07f12ae64a.webp 960w, https://francisdu.com/img/wcode/wcode-architecture_hu_3f3f08e508cea449.webp 1800w&#34; sizes=&#34;(max-width: 900px) calc(100vw - 32px), 900px&#34; width=&#34;3232&#34; height=&#34;1932&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;我为什么没有把所有查询都切到-lsp&#34;&gt;我为什么没有把所有查询都切到 LSP&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e6%88%91%e4%b8%ba%e4%bb%80%e4%b9%88%e6%b2%a1%e6%9c%89%e6%8a%8a%e6%89%80%e6%9c%89%e6%9f%a5%e8%af%a2%e9%83%bd%e5%88%87%e5%88%b0-lsp&#34; aria-label=&#34;章节链接：我为什么没有把所有查询都切到 LSP&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;最直接的做法其实很诱人：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;既然 Language Server 更懂代码，那以后 Definition、Search、Reference、Call 全走 LSP 不就好了？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我试着沿这个方向想了一轮，最后放弃了。&lt;/p&gt;
&lt;p&gt;原因是 Agent Coding 里有两类完全不同的问题。&lt;/p&gt;
&lt;p&gt;第一类只是定位：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这个函数在哪？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;这个 Struct 定义在哪？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;哪个文件包含这个字符串？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这类问题 Tree-sitter / Search 很便宜，而且稳定，不需要启动项目语义环境。&lt;/p&gt;
&lt;p&gt;第二类才是真正需要 Semantic Completeness 的关系问题：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;references
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;implementations
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;incoming callers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;outgoing callees
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rename impact
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果为了第一类问题也默认走 Language Server，就会把一个本来很便宜的定位动作变成进程启动、Initialize、Document Sync、Semantic Query。&lt;/p&gt;
&lt;p&gt;而 Agent 还有一个额外成本：Tool Result 最后会进入 Context。&lt;/p&gt;
&lt;p&gt;所以我现在更愿意把两层能力分开：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                ┌──────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                │     agent_context     │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                └──────────┬───────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                普通定位   │   跨文件关系
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          ┌────────────────┴───────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          ↓                                ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;find_symbol / search_code          semantic_navigation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Tree-sitter / text search                 │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │                               ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │                       Warm LSP Session
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          └──────────────┬────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    edit / review
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                         ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    verify_project
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;不是“LSP 比 grep 高级，所以替掉 grep”。&lt;/p&gt;
&lt;p&gt;而是让每一层只解决它真正擅长的问题。&lt;/p&gt;
&lt;h2 id=&#34;以前的-lsp-其实还是一次性工具&#34;&gt;以前的 LSP 其实还是一次性工具&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e4%bb%a5%e5%89%8d%e7%9a%84-lsp-%e5%85%b6%e5%ae%9e%e8%bf%98%e6%98%af%e4%b8%80%e6%ac%a1%e6%80%a7%e5%b7%a5%e5%85%b7&#34; aria-label=&#34;章节链接：以前的 LSP 其实还是一次性工具&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;wcode 之前已经能跑 Language Server。&lt;/p&gt;
&lt;p&gt;但生命周期很像一个 Batch Job：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;start provider
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;initialize
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;didOpen
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Document Symbol
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Call Hierarchy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Implementation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;shutdown
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;它适合定期补 Software Graph。&lt;/p&gt;
&lt;p&gt;但如果 Agent 紧接着又问一次 Reference，就要重新付一遍启动成本。&lt;/p&gt;
&lt;p&gt;更关键的是，这种模型下“Semantic Provider”在架构上仍然只是一个索引器，不是真正的 Runtime。&lt;/p&gt;
&lt;p&gt;v0.5 把这个生命周期改了。&lt;/p&gt;
&lt;p&gt;现在 Harness 里有一个有界 Session Pool：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Provider + Binary Identity
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Warm Session Slot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├── graph refresh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├── semantic_navigation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├── didChange
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └── didClose
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同一个 Workspace 下，后台 Graph Indexing 和前台 Navigation 会复用同一个 Provider Process。&lt;/p&gt;
&lt;p&gt;如果 &lt;code&gt;rust-analyzer&lt;/code&gt; 已经 Warm，第二次查 Caller 不需要再启动一遍。&lt;/p&gt;
&lt;h2 id=&#34;warm-不等于永远不关&#34;&gt;Warm 不等于永远不关&lt;a class=&#34;heading-anchor&#34; href=&#34;#warm-%e4%b8%8d%e7%ad%89%e4%ba%8e%e6%b0%b8%e8%bf%9c%e4%b8%8d%e5%85%b3&#34; aria-label=&#34;章节链接：Warm 不等于永远不关&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;我不想为了省启动成本，最后在后台养一堆永远不会退出的 Language Server。&lt;/p&gt;
&lt;p&gt;所以这个 Pool 从一开始就是 Bounded 的。&lt;/p&gt;
&lt;p&gt;它有几条约束：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Session 数量有上限；&lt;/li&gt;
&lt;li&gt;Idle Slot 会淘汰；&lt;/li&gt;
&lt;li&gt;同一个 Slot 的 JSON-RPC Stream 串行处理；&lt;/li&gt;
&lt;li&gt;Provider Process 死掉以后重建；&lt;/li&gt;
&lt;li&gt;Provider Binary Identity 变了以后重建；&lt;/li&gt;
&lt;li&gt;Workspace Key 不共享到别的项目；&lt;/li&gt;
&lt;li&gt;离开当前有界索引集合的 Document 会 &lt;code&gt;didClose&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;发版前我专门沿这条生命周期又审了一遍，结果真的抓到一个边界 Bug：最初的 Idle Eviction 其实是 Lazy 的，只有下一次有人访问 Session Pool 时才会 Prune；更糟一点，容量满时如果直接从 Map 里移除“最旧 Slot”，这个 Slot 可能还被一个 Active Request 持有，于是 Map 看起来仍然只有 16 个，实际进程却可能短暂跑到第 17 个。&lt;/p&gt;
&lt;p&gt;最后我把规则改成了更保守的版本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Idle + unleased
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 可以 prune
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;capacity full + 有 unleased slot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 只驱逐 unleased slot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;capacity full + 全部 leased
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → fail closed / retry
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;provider binary changed + old slot still leased
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 等当前 request 结束
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 再替换
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Background Semantic Coordinator 也会周期性主动 Prune，所以即使是没有 TUI 交互的 &lt;code&gt;mcp-stdio&lt;/code&gt;，Idle Bound 也不是一句文档里的承诺。&lt;/p&gt;
&lt;p&gt;源码变化也不是简单把 Process 杀掉重启。&lt;/p&gt;
&lt;p&gt;现在不是强行给所有 Server 发同一种 Notification，而是先看它在 &lt;code&gt;initialize&lt;/code&gt; 里声明的 &lt;code&gt;textDocumentSync&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Full
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Open 发完整内容
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Change 发整文档
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Incremental
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Open 发完整内容
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Change 用旧文档范围做合法 replacement
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Range 按协商的 UTF-8 / UTF-16 / UTF-32 算
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;None / openClose=false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 不硬发 Server 没声明支持的 Notification
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Server 继续从磁盘读取
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;只有 Server 要求 Open/Close Sync 时才发 &lt;code&gt;didOpen&lt;/code&gt; / &lt;code&gt;didClose&lt;/code&gt;。这才比较像我理解的“常驻语义层”：它既知道当前 Document Revision，也尊重每个 Language Server 自己的同步协议，而不是假定 Rust 能工作的 Change Shape 对 22 种语言都成立。&lt;/p&gt;
&lt;h2 id=&#34;semantic_navigation-不让-agent-自己算-utf-16&#34;&gt;&lt;code&gt;semantic_navigation&lt;/code&gt; 不让 Agent 自己算 UTF-16&lt;a class=&#34;heading-anchor&#34; href=&#34;#semantic_navigation-%e4%b8%8d%e8%ae%a9-agent-%e8%87%aa%e5%b7%b1%e7%ae%97-utf-16&#34; aria-label=&#34;章节链接：semantic_navigation 不让 Agent 自己算 UTF-16&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;做 Agent Tool 时，我越来越不喜欢把底层协议细节原样扔给模型。&lt;/p&gt;
&lt;p&gt;原始 LSP 通常希望调用方给：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;file URI
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;line
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;character
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;position encoding
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后不同 Server 还可能用 UTF-8 / UTF-16 Position Encoding。&lt;/p&gt;
&lt;p&gt;让模型自己根据源码去算 UTF-16 Offset，我觉得完全是在浪费模型能力，而且很容易在非 ASCII 代码里漂掉。&lt;/p&gt;
&lt;p&gt;所以 v0.5 的 &lt;code&gt;semantic_navigation&lt;/code&gt; 主入口是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;path + symbol
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;wcode 自己先用 Tree-sitter 找 Symbol 的精确位置，再根据 Language Server Initialize 时协商到的 Encoding 转换 Position。&lt;/p&gt;
&lt;p&gt;Agent 只需要表达意图：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;definition
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hover
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;references
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;incoming_calls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;outgoing_calls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;implementations
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;impact
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;真正已经持有精确 Position 的调用方，也可以继续传 &lt;code&gt;line + character&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这件事看起来很小，但我觉得它代表一个方向：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LSP Primitive 不应该直接等于 Agent Primitive。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Agent Tool 应该封装成模型真正想问的问题，而不是要求模型先学会协议的坐标系。&lt;/p&gt;
&lt;p&gt;这里发版审计又抓到另一个我不愿意留到 0.5.1 的问题：最早实现里，如果 Server 声明支持 &lt;code&gt;references&lt;/code&gt;，但这次 Request 实际 Timeout / Error，结果路径可能最后只留下一个空数组。对 Agent 来说，“请求失败”和“确实没有 Reference”完全不是一件事。&lt;/p&gt;
&lt;p&gt;所以现在 Result 会明确分成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;unsupported
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Server 没这个能力
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;failures
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Server 有能力，但这次 LSP Request 失败
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;relationships = []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → Request 成功，真的没有匹配关系
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我尤其不想让失败被当成 Negative Semantic Evidence。语义系统最危险的不是“不知道”，而是失败以后还表现得像自己很确定。&lt;/p&gt;
&lt;h2 id=&#34;22-种语言不能只有-rust-真正跑得通&#34;&gt;22 种语言，不能只有 Rust 真正跑得通&lt;a class=&#34;heading-anchor&#34; href=&#34;#22-%e7%a7%8d%e8%af%ad%e8%a8%80%e4%b8%8d%e8%83%bd%e5%8f%aa%e6%9c%89-rust-%e7%9c%9f%e6%ad%a3%e8%b7%91%e5%be%97%e9%80%9a&#34; aria-label=&#34;章节链接：22 种语言，不能只有 Rust 真正跑得通&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;发版前我又给这版加了一条更苛刻的要求：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;既然 wcode 对外说 Syntax Index 支持 22 种语言，那 LSP 层也不能只把 rust-analyzer 做扎实，其他语言只在 Registry 里挂个名字。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这次审计以后，我把“支持”拆成了三个完全不同的概念：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Compatibility
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → wcode 有没有正确的 Provider Adapter / Command / Language ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Installation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 用户机器上有没有真的装这个 Language Server
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Live Semantic
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 这个已安装 Server 有没有真实 initialize 并回答当前 Revision
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;只有第一层是 wcode 在 Build/Test 阶段能 100% 保证的。&lt;/p&gt;
&lt;p&gt;第二层取决于用户机器。&lt;/p&gt;
&lt;p&gt;第三层必须等 Runtime 真正和 Server 完成 LSP Handshake 以后才能成立。&lt;/p&gt;
&lt;p&gt;所以 v0.5 现在要求 22 种 Indexed Language &lt;strong&gt;每一种恰好只有一个 Canonical LSP Launch Profile&lt;/strong&gt;，并用测试把映射和 Provider-specific Argument 锁死。除此之外，我还加了一层跨平台 stdio Mock LSP：每一个 Canonical Profile 都会真的 Spawn 一个子进程，完成 &lt;code&gt;initialize&lt;/code&gt;、Capability Negotiation、Open/Change/Close 和 Hover JSON-RPC 往返，而不是只检查数组里的字符串：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Language&lt;/th&gt;
					&lt;th&gt;Canonical LSP&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Bash&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;bash-language-server start&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;C / C++&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;clangd&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;C#&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;csharp-ls&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CSS&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;vscode-css-language-server --stdio&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Dart&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;dart language-server --protocol=lsp&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Elixir&lt;/td&gt;
					&lt;td&gt;ElixirLS &lt;code&gt;language_server.sh&lt;/code&gt; / Wrapper&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Go&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;gopls serve&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HTML&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;vscode-html-language-server --stdio&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Java&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;jdtls -data &amp;lt;unique state&amp;gt;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;JavaScript / TypeScript / TSX&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;typescript-language-server --stdio&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Lua&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;lua-language-server&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;OCaml / Interface&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;ocamllsp&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PHP&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;phpactor language-server&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Python&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;pyright-langserver --stdio&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;R&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;R --no-echo -e languageserver::run()&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Ruby&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;ruby-lsp&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Rust&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;rust-analyzer&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Swift&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sourcekit-lsp&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;而且这次不是把旧 Registry 原样拿来写测试。&lt;/p&gt;
&lt;p&gt;我对着各家的当前启动方式重新过了一遍，确实发现了几个容易变成“纸面支持”的地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go 明确改成 &lt;code&gt;gopls serve&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;JDT LS 会拿一个 Workspace + Runtime 唯一的用户级 &lt;code&gt;-data&lt;/code&gt; 目录，避免两个项目或两个 wcode Process 共用 JDT State；&lt;/li&gt;
&lt;li&gt;Dart 使用 &lt;code&gt;dart language-server --protocol=lsp&lt;/code&gt;，并带上 wcode 的 Client ID / Version；&lt;/li&gt;
&lt;li&gt;Elixir 同时识别官方 &lt;code&gt;language_server.sh&lt;/code&gt;、Windows Wrapper 和常见发行版 &lt;code&gt;elixir-ls&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;LuaLS 对 Symlink 启动比较特殊，所以不能照抄 rustup Proxy 的处理方式，发现 Symlink 时会执行 Canonical Target；&lt;/li&gt;
&lt;li&gt;OmniSharp 的 &lt;code&gt;-lsp&lt;/code&gt; 不再被拿来凑 C# Fallback 数量，C# Canonical 路径只认 &lt;code&gt;csharp-ls&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;真正有意义的 Alternate 只留了三个：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PHP     phpactor → intelephense
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Python  pyright  → pylsp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ruby    ruby-lsp → solargraph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;更重要的是，Fallback 不是只存在配置表里。&lt;/p&gt;
&lt;p&gt;现在 &lt;code&gt;semantic_navigation&lt;/code&gt; 和手工 &lt;code&gt;semantic_provider_refresh&lt;/code&gt; 都会在：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;canonical executable exists
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;initialize fails
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;try installed alternate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但 Alternate 不会继承 Canonical Provider 的授权。&lt;/p&gt;
&lt;p&gt;如果它属于非 Automatic Provider，就必须拿自己的 Workspace + Provider + Binary Identity Trust；Refresh 成功切换以后，结果里还会显式记录 &lt;code&gt;fallbacks&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;所以这里我想表达的不是“wcode 自带 22 个 Language Server”。&lt;/p&gt;
&lt;p&gt;它当然没有。&lt;/p&gt;
&lt;p&gt;而是：&lt;strong&gt;22/22 的 Adapter Contract、stdio Framing 和 Provider-specific Launch Profile 是 wcode 自己要负责的；External Server 是否安装要诚实报告；Semantic Precision 只有那份真实 Binary Live Initialize + 当前 Revision Response 以后才成立。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这比在 README 里写一个长长的“Supported Languages”列表可靠得多。&lt;/p&gt;
&lt;h2 id=&#34;默认开启以后安全边界反而要更严格&#34;&gt;默认开启以后，安全边界反而要更严格&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e9%bb%98%e8%ae%a4%e5%bc%80%e5%90%af%e4%bb%a5%e5%90%8e%e5%ae%89%e5%85%a8%e8%be%b9%e7%95%8c%e5%8f%8d%e8%80%8c%e8%a6%81%e6%9b%b4%e4%b8%a5%e6%a0%bc&#34; aria-label=&#34;章节链接：默认开启以后，安全边界反而要更严格&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这次另一个比较大的决定，是 Hardened Semantic 默认开启。&lt;/p&gt;
&lt;p&gt;也就是说普通启动：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wcode --workspace &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt;$PWD&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果项目里有 Rust，而且系统里有可用的 &lt;code&gt;rust-analyzer&lt;/code&gt;，wcode 会自动维护这条 Semantic Lane。&lt;/p&gt;
&lt;p&gt;但我没有把“所有 LSP 默认信任”一起打开。&lt;/p&gt;
&lt;p&gt;v0.5 当前只有 &lt;code&gt;rust-analyzer&lt;/code&gt; 进入 Automatic Profile。&lt;/p&gt;
&lt;p&gt;因为 Language Server 和普通 Parser 不一样：它会读项目配置，有些 Server 甚至可能间接执行 Repository-controlled Code。&lt;/p&gt;
&lt;p&gt;所以默认 Profile 做了几层限制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Executable 必须解析到 Workspace 外；&lt;/li&gt;
&lt;li&gt;Workspace 里的假 &lt;code&gt;rust-analyzer&lt;/code&gt; 不会被执行；&lt;/li&gt;
&lt;li&gt;Credential 和 Execution-injection Environment Variable 会清理；&lt;/li&gt;
&lt;li&gt;Build Script 关闭；&lt;/li&gt;
&lt;li&gt;Proc Macro 关闭；&lt;/li&gt;
&lt;li&gt;Cargo Auto Reload 关闭；&lt;/li&gt;
&lt;li&gt;Check-on-save 关闭；&lt;/li&gt;
&lt;li&gt;Result 最后仍重新经过 Workspace Boundary Filter。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这不是 OS Sandbox。&lt;/p&gt;
&lt;p&gt;我不想用“安全模式”这种词让人误以为 Language Server 完全没有执行面。&lt;/p&gt;
&lt;p&gt;它只是一个我愿意默认打开的、被明显收窄过的 Profile。&lt;/p&gt;
&lt;p&gt;如果是 &lt;code&gt;clangd&lt;/code&gt;、Pyright、gopls 或其他当前还没有 Hardened Profile 的 Provider，仍然需要显式 &lt;code&gt;RiskyExecution&lt;/code&gt; Trust。&lt;/p&gt;
&lt;p&gt;而且 Warm Session 出现以后，授权语义也跟着变了。&lt;/p&gt;
&lt;p&gt;以前一次性 Provider 可以按某次 Refresh Operation 授权。&lt;/p&gt;
&lt;p&gt;现在 Process 会被复用，真正准确的 Trust 应该是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  + Provider
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  + current Provider Binary Identity
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个 Binary Identity 也不能漏。发版审计时我发现，第一版 Provider-session Fingerprint 只绑定了 Provider ID；如果 PATH 上同名 Provider Binary 被替换，Session Key 会重建，但旧授权理论上仍可能继续适用。现在 Authorization 和 Warm Session 使用同一套 Provider Binary Identity：Executable 被替换以后，旧 Grant 不会继承过去。&lt;/p&gt;
&lt;p&gt;因此同一份已批准 Provider 可以被 Refresh 和 Navigation 复用，不会每问一次 Reference 又弹一次权限；但它也不会顺手授权替换后的 Binary。&lt;/p&gt;
&lt;p&gt;如果完全不希望 wcode 启动第一方 Language Server：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wcode --workspace &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt;$PWD&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt; --no-semantic
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tree-sitter / Search 仍然都在。&lt;/p&gt;
&lt;h2 id=&#34;后台自动维护也不能绕过全局资源边界&#34;&gt;后台自动维护也不能绕过全局资源边界&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e5%90%8e%e5%8f%b0%e8%87%aa%e5%8a%a8%e7%bb%b4%e6%8a%a4%e4%b9%9f%e4%b8%8d%e8%83%bd%e7%bb%95%e8%bf%87%e5%85%a8%e5%b1%80%e8%b5%84%e6%ba%90%e8%be%b9%e7%95%8c&#34; aria-label=&#34;章节链接：后台自动维护也不能绕过全局资源边界&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;另一个我不想接受的状态是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;前台 Tool 都有 Global Semaphore，后台 Semantic Worker 却偷偷无限跑。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;那 TUI 上看到的并发数就会是假的。&lt;/p&gt;
&lt;p&gt;所以 Background Semantic Maintainer 也必须先拿 Harness Permit，再真正进入 Running。&lt;/p&gt;
&lt;p&gt;生命周期还是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;queued
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acquire global permit
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;running
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;completed / failed
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Broad Workspace 下面如果还有具体 Project Subspace，也只让最具体的 Leaf Workspace 启动自动 Semantic Worker。&lt;/p&gt;
&lt;p&gt;不然我把 &lt;code&gt;~/Code&lt;/code&gt; 暴露给 wcode 时，父目录和十几个子项目会同时索引同一批源码。&lt;/p&gt;
&lt;p&gt;这种优化不会出现在“支持哪些 LSP”的 Feature List 里，但我觉得比多支持一个 Server 更重要。&lt;/p&gt;
&lt;h2 id=&#34;tui-现在能看出-warm-到底有没有生效&#34;&gt;TUI 现在能看出 Warm 到底有没有生效&lt;a class=&#34;heading-anchor&#34; href=&#34;#tui-%e7%8e%b0%e5%9c%a8%e8%83%bd%e7%9c%8b%e5%87%ba-warm-%e5%88%b0%e5%ba%95%e6%9c%89%e6%b2%a1%e6%9c%89%e7%94%9f%e6%95%88&#34; aria-label=&#34;章节链接：TUI 现在能看出 Warm 到底有没有生效&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;以前 TUI 的 LSP 状态主要是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;available / runnable
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fresh / stale
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;v0.5 现在还会显示：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;warm sessions
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;synced documents
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;provider starts
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;semantic queries
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我特意加这些，不是为了让 Dashboard 再多几个数字。&lt;/p&gt;
&lt;p&gt;而是 Warm Runtime 最容易出现一种假优化：代码里写了 Cache，但实际上每次 Query 还是重启 Process。&lt;/p&gt;
&lt;p&gt;如果 Session Start 一直涨、Query 也一直涨，那我就知道复用没有真的工作。&lt;/p&gt;
&lt;p&gt;可观测性是性能优化的一部分，不是最后补的 UI。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-tui_hu_13e59e78ee0ce797.webp&#34; alt=&#34;wcode TUI&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34; srcset=&#34;https://francisdu.com/img/wcode/wcode-tui_hu_13e59e78ee0ce797.webp 960w, https://francisdu.com/img/wcode/wcode-tui_hu_6437a17a51f06ca3.webp 1800w&#34; sizes=&#34;(max-width: 900px) calc(100vw - 32px), 900px&#34; width=&#34;3420&#34; height=&#34;2146&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;v04-和-v05-的差别&#34;&gt;v0.4 和 v0.5 的差别&lt;a class=&#34;heading-anchor&#34; href=&#34;#v04-%e5%92%8c-v05-%e7%9a%84%e5%b7%ae%e5%88%ab&#34; aria-label=&#34;章节链接：v0.4 和 v0.5 的差别&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;如果 v0.4 是“让 Intelligence 不要变成 Context Tax”，v0.5 更像是“让语义能力真正进入日常 Coding Hot Path”。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;v0.4&lt;/th&gt;
					&lt;th&gt;v0.5&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Semantic Provider&lt;/td&gt;
					&lt;td&gt;有界 Batch Refresh&lt;/td&gt;
					&lt;td&gt;Bounded Warm Runtime&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LSP Process&lt;/td&gt;
					&lt;td&gt;Refresh 后退出&lt;/td&gt;
					&lt;td&gt;Workspace Session 复用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Document Sync&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;didOpen&lt;/code&gt; 为主&lt;/td&gt;
					&lt;td&gt;Server-declared Full / Incremental / None&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Agent Navigation&lt;/td&gt;
					&lt;td&gt;Syntax + Graph Context&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;semantic_navigation&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Default Routing&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;agent_context&lt;/code&gt; + Tree-sitter&lt;/td&gt;
					&lt;td&gt;Localization 走 Syntax，Relationship 才走 LSP&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Automatic Trust&lt;/td&gt;
					&lt;td&gt;LSP 需要显式 Trust&lt;/td&gt;
					&lt;td&gt;Hardened &lt;code&gt;rust-analyzer&lt;/code&gt; 默认开启&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Non-auto LSP&lt;/td&gt;
					&lt;td&gt;Exact Refresh Trust&lt;/td&gt;
					&lt;td&gt;Workspace + Provider Session &lt;code&gt;RiskyExecution&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;TUI&lt;/td&gt;
					&lt;td&gt;available / fresh&lt;/td&gt;
					&lt;td&gt;available → launch-ready → live + warm/fresh&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;我觉得这已经不是 0.4.x 的 Patch。&lt;/p&gt;
&lt;p&gt;所以版本直接到了 &lt;strong&gt;v0.5.0&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;这次发版我也把-release-boundary-再收紧了一次&#34;&gt;这次发版我也把 Release Boundary 再收紧了一次&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e8%bf%99%e6%ac%a1%e5%8f%91%e7%89%88%e6%88%91%e4%b9%9f%e6%8a%8a-release-boundary-%e5%86%8d%e6%94%b6%e7%b4%a7%e4%ba%86%e4%b8%80%e6%ac%a1&#34; aria-label=&#34;章节链接：这次发版我也把 Release Boundary 再收紧了一次&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Milestone Release 最怕的不是功能没写完，而是“仓库里的版本看起来有六个答案”。&lt;/p&gt;
&lt;p&gt;wcode 现在除了 Cargo Version，还有 Agent Plugin / Marketplace Manifest。&lt;/p&gt;
&lt;p&gt;v0.5 发版前我把它们统一成同一个版本，并且不只依赖 CI Shell Script 检查。&lt;/p&gt;
&lt;p&gt;Unit Test 也会验证：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Cargo package version
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  == plugin.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  == Claude plugin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  == Codex plugin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  == ZCode plugin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  == root marketplace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  == plugin marketplace
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Release Workflow 还会再独立检查一次，然后跑：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Design / Traceability / Product Scope gate
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Format
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Check
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Clippy --all-targets
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Linux test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;macOS test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Windows test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Linux / macOS / Windows release build
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;binary --version
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SHA256SUMS
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这次 Tag 前最后一轮本地 Full Gate 是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git diff --check                       ✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo check --locked                   ✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo fmt --check                      ✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo test --locked                    ✅ 270 passed / 0 failed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo clippy --locked -- -D warnings   ✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo build --release --locked         ✅
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里的 270 个核心测试已经包含 22 个 Canonical Profile 的真实 stdio Mock-LSP Initialize Contract、Full/Incremental/None Document Sync、Warm Session Capacity/Idle、Provider Binary Trust、Fallback 和 Navigation Failure Semantics。&lt;/p&gt;
&lt;p&gt;我仍然不想把“本机 cargo test 绿了”直接等同于“Release 已经成立”。&lt;/p&gt;
&lt;p&gt;真正发布的是 Tagged Revision 和对应 Artifact；Linux/macOS/Windows 的最终跨平台结论继续交给 Tag CI。&lt;/p&gt;
&lt;h2 id=&#34;最后&#34;&gt;最后&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e6%9c%80%e5%90%8e&#34; aria-label=&#34;章节链接：最后&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;wcode 最开始只是我为了让 Web AI 安全碰本地代码写的一层 MCP Bridge。&lt;/p&gt;
&lt;p&gt;后来它慢慢有了 Design State、Software Graph、Verification、Evidence、Reconciliation。&lt;/p&gt;
&lt;p&gt;v0.4 我开始对 Agent 的 Context 成本负责。&lt;/p&gt;
&lt;p&gt;到 v0.5，我又多了一层判断：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;代码智能不应该只有“便宜但不完整”和“准确但每次很重”两个极端。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Tree-sitter / Search 可以一直做便宜、稳定的定位底座。&lt;/p&gt;
&lt;p&gt;Language Server 则应该在真正需要关系完整性的地方，以受限、可复用、可观测的 Runtime 形式出现。&lt;/p&gt;
&lt;p&gt;不是把所有东西都升级成 LSP。&lt;/p&gt;
&lt;p&gt;而是让 Agent 知道：什么时候 Syntax 已经够了，什么时候值得支付 Semantic Cost。&lt;/p&gt;
&lt;p&gt;这应该会是后面 wcode Semantic Runtime 继续扩展其他语言时最重要的一条原则。&lt;/p&gt;
&lt;p&gt;代码：&lt;a href=&#34;https://github.com/francis-du/wcode&#34;&gt;https://github.com/francis-du/wcode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;文档：&lt;a href=&#34;https://wcode.francis.run/&#34;&gt;https://wcode.francis.run/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;v0.5.0 Release Notes：&lt;a href=&#34;https://wcode.francis.run/docs/releases/v0.5.0/&#34;&gt;https://wcode.francis.run/docs/releases/v0.5.0/&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>wcode v0.4：我开始压 Context 和 Tool Call</title>
      <link>https://francisdu.com/blog/wcode-v0-4/</link>
      <pubDate>Thu, 27 Aug 2026 23:55:00 +0800</pubDate>
      <guid>https://francisdu.com/blog/wcode-v0-4/</guid>
      <description>&lt;p&gt;v0.3 做完以后，wcode 已经有 Design State、Software Graph、Traceability、Risk、Verification、Evidence、Reconciliation 和 Project Observatory。&lt;/p&gt;
&lt;p&gt;从“能力列表”看，其实已经很多了。&lt;/p&gt;
&lt;p&gt;但我拿它真的去写几个项目以后，最明显的问题反而很朴素：Agent 已经知道怎么做了，前面还是花了太多 Context 和 Tool Call。&lt;/p&gt;
&lt;p&gt;所以 v0.4 我先没加新的大能力，主要把写代码这条默认路径重新压了一遍。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-tui_hu_13e59e78ee0ce797.webp&#34; alt=&#34;wcode 最新终端实时面板&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34; srcset=&#34;https://francisdu.com/img/wcode/wcode-tui_hu_13e59e78ee0ce797.webp 960w, https://francisdu.com/img/wcode/wcode-tui_hu_6437a17a51f06ca3.webp 1800w&#34; sizes=&#34;(max-width: 900px) calc(100vw - 32px), 900px&#34; width=&#34;3420&#34; height=&#34;2146&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;v04-先不加大功能&#34;&gt;v0.4 先不加大功能&lt;a class=&#34;heading-anchor&#34; href=&#34;#v04-%e5%85%88%e4%b8%8d%e5%8a%a0%e5%a4%a7%e5%8a%9f%e8%83%bd&#34; aria-label=&#34;章节链接：v0.4 先不加大功能&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.3 我最关心的是“软件状态能不能留下来”。&lt;/p&gt;
&lt;p&gt;所以那一版的主线是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Design State
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Software Graph
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Drift / Impact / Risk
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Verification / Evidence
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Reconciliation
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这些东西 v0.4 都还在。&lt;/p&gt;
&lt;p&gt;但如果一个 Agent 每次只是改两行代码，也要先完整走一遍 Design、Graph、Traceability、Risk，再查 Symbol、再读文件，那这套系统会越来越像“为了完整而完整”。&lt;/p&gt;
&lt;p&gt;我不想让 Intelligence 本身变成新的 Context Tax。&lt;/p&gt;
&lt;p&gt;所以 v0.4 的默认 Coding Path 变成了：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;agent_context
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;必要时补 symbol_context
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apply_edits / apply_file_edits
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;review_changes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;verify_project
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;更深的 Design、Graph、Risk、Reconciliation 还在，但变成按任务需要进入，而不是每次启动都强制付费。&lt;/p&gt;
&lt;h2 id=&#34;agent_context-成了真正的-coding-entry-point&#34;&gt;&lt;code&gt;agent_context&lt;/code&gt; 成了真正的 Coding Entry Point&lt;a class=&#34;heading-anchor&#34; href=&#34;#agent_context-%e6%88%90%e4%ba%86%e7%9c%9f%e6%ad%a3%e7%9a%84-coding-entry-point&#34; aria-label=&#34;章节链接：agent_context 成了真正的 Coding Entry Point&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这一版我加了一个 Agent Context Compiler。&lt;/p&gt;
&lt;p&gt;它不是简单把几个 Tool Result 拼起来，而是尝试一次返回“现在就可以开始修改”的最小上下文。&lt;/p&gt;
&lt;p&gt;一个典型结果里会有：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;任务相关 Design / Constraint
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Direct Target
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Exact SHA
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Scoped Repo Map
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Related Symbol / Test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Working-tree Advisory
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Readiness
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Next Actions
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;必要时的 Hot Source
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我最在意的是最后几个东西。&lt;/p&gt;
&lt;p&gt;以前 Agent 经常出现这种链：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;project_context
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;→ search
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;→ find_symbol
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;→ read_file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;→ 再 search
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;→ 再 read_file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;→ edit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;每一步都合理，但累计起来 Tool Round-trip 很多，而且每次响应都会重新占一部分 Context。&lt;/p&gt;
&lt;p&gt;现在如果任务足够明确，&lt;code&gt;agent_context&lt;/code&gt; 可以直接把最强目标连同 SHA 和一小段 Hot Source 带回来。&lt;/p&gt;
&lt;p&gt;常见的小修改就能变成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;agent_context → edit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这对我来说比“又多支持一个 Tool”有意义得多。&lt;/p&gt;
&lt;h2 id=&#34;context-budget-不应该永远是一个固定数字&#34;&gt;Context Budget 不应该永远是一个固定数字&lt;a class=&#34;heading-anchor&#34; href=&#34;#context-budget-%e4%b8%8d%e5%ba%94%e8%af%a5%e6%b0%b8%e8%bf%9c%e6%98%af%e4%b8%80%e4%b8%aa%e5%9b%ba%e5%ae%9a%e6%95%b0%e5%ad%97&#34; aria-label=&#34;章节链接：Context Budget 不应该永远是一个固定数字&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;以前 &lt;code&gt;software_context&lt;/code&gt; 更像一个固定预算的 Query。&lt;/p&gt;
&lt;p&gt;但真实 Coding Task 差别很大。&lt;/p&gt;
&lt;p&gt;改一个错误文案和改一个跨 Runtime / MCP / Workspace 的安全问题，不应该拿同样大的上下文。&lt;/p&gt;
&lt;p&gt;所以 v0.4 里，&lt;code&gt;agent_context&lt;/code&gt; 在不显式传 Budget 时会做 Adaptive Budget。&lt;/p&gt;
&lt;p&gt;大致思路是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;明确单点任务
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 小 Context
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;目标不确定 / 跨模块
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 给更多 Context
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;始终有 Hard Bound
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个优化看起来不如 Graph 或 Verification “大”，但 Agent 每一次调用都会碰到它。&lt;/p&gt;
&lt;p&gt;我现在越来越觉得，做 Agent Runtime 不能只优化模型能不能完成任务，还要开始对&lt;strong&gt;每次完成任务花了多少上下文&lt;/strong&gt;负责。&lt;/p&gt;
&lt;h2 id=&#34;repo-map-也不能每次扫完整仓库&#34;&gt;Repo Map 也不能每次扫完整仓库&lt;a class=&#34;heading-anchor&#34; href=&#34;#repo-map-%e4%b9%9f%e4%b8%8d%e8%83%bd%e6%af%8f%e6%ac%a1%e6%89%ab%e5%ae%8c%e6%95%b4%e4%bb%93%e5%ba%93&#34; aria-label=&#34;章节链接：Repo Map 也不能每次扫完整仓库&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Agent Context 里最容易膨胀的是 Repo Map。&lt;/p&gt;
&lt;p&gt;如果一句任务已经明确属于 &lt;code&gt;workspace&lt;/code&gt; Scope，而且目标文件也很直接，再把 Runtime、UI、Graph、Verification 全仓库结构都送进去没有意义。&lt;/p&gt;
&lt;p&gt;所以现在 Repo Map 有几层变化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scope-aware；&lt;/li&gt;
&lt;li&gt;Cold Build 时尽量只构造相关区域；&lt;/li&gt;
&lt;li&gt;Structure 按 Revision Cache；&lt;/li&gt;
&lt;li&gt;每个 Query 只重算 Ranking；&lt;/li&gt;
&lt;li&gt;多 Query Symbol Search 对一个 Source Root 只扫描一次；&lt;/li&gt;
&lt;li&gt;Fresh Semantic / Runtime Evidence 可以提高相关 Caller / Dependency 排名；&lt;/li&gt;
&lt;li&gt;Semantic Revision 过期以后自动退回 Syntax，不继续拿旧事实指导 Agent。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我还把这些东西做了 Telemetry。&lt;/p&gt;
&lt;p&gt;TUI 现在可以看到 Agent Context Calls、平均 Model-visible Token、Repo-map Cache Hit，以及大概省掉了多少 Context。&lt;/p&gt;
&lt;p&gt;不是为了做一个漂亮数字，而是我想以后优化时至少知道自己到底有没有真的减少模型负担。&lt;/p&gt;
&lt;h2 id=&#34;project-observatory-终于先讲架构而不是先讲需求列表&#34;&gt;Project Observatory 终于先讲架构，而不是先讲需求列表&lt;a class=&#34;heading-anchor&#34; href=&#34;#project-observatory-%e7%bb%88%e4%ba%8e%e5%85%88%e8%ae%b2%e6%9e%b6%e6%9e%84%e8%80%8c%e4%b8%8d%e6%98%af%e5%85%88%e8%ae%b2%e9%9c%80%e6%b1%82%e5%88%97%e8%a1%a8&#34; aria-label=&#34;章节链接：Project Observatory 终于先讲架构，而不是先讲需求列表&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.3 的 Project Observatory 已经从“Graph 球图”改成了 Requirement-first。&lt;/p&gt;
&lt;p&gt;到 v0.4 我又改了一次。&lt;/p&gt;
&lt;p&gt;现在进去先看到的是&lt;strong&gt;整体 Component Architecture&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;原因也很简单：&lt;/p&gt;
&lt;p&gt;当我要理解一个陌生项目时，我通常第一句不是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这个 Requirement 现在状态怎么样？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这个项目到底分成哪几块，它们怎么依赖？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以现在 Observatory 会先把 Design 里声明的 Dependency 和代码里真实观测到的 Relationship 叠在一起。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Design Architecture
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        +
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Observed Implementation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Overlay
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;并且继续保留 Provider / Precision。&lt;/p&gt;
&lt;p&gt;这点我没有妥协：Tree-sitter 没看到某个关系，不等于关系不存在；只有真实 Semantic / Runtime / Deterministic Evidence 才能把某些 Observed Drift 升级成更强的判断。&lt;/p&gt;
&lt;p&gt;UI 里也不再给一个模糊的“Health Score”，而是拆成可以解释的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Observed Drift；&lt;/li&gt;
&lt;li&gt;Evidence Coverage；&lt;/li&gt;
&lt;li&gt;Implementation Coverage。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我更愿意看到几个不完美但能解释的指标，也不想看到一个 87 分却不知道为什么是 87。&lt;/p&gt;
&lt;h2 id=&#34;我还是不想给-agent-一个-shell但开发命令不能太残废&#34;&gt;我还是不想给 Agent 一个 Shell，但开发命令不能太残废&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e6%88%91%e8%bf%98%e6%98%af%e4%b8%8d%e6%83%b3%e7%bb%99-agent-%e4%b8%80%e4%b8%aa-shell%e4%bd%86%e5%bc%80%e5%8f%91%e5%91%bd%e4%bb%a4%e4%b8%8d%e8%83%bd%e5%a4%aa%e6%ae%8b%e5%ba%9f&#34; aria-label=&#34;章节链接：我还是不想给 Agent 一个 Shell，但开发命令不能太残废&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;wcode 一直坚持 No-shell Boundary。&lt;/p&gt;
&lt;p&gt;但 v0.3 之后我自己使用时也碰到一个现实问题：真正开发不可能永远只有 &lt;code&gt;cargo test&lt;/code&gt; 和 &lt;code&gt;git status&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;所以 v0.4 扩了很多 Command Policy，不过方向不是“放开命令”，而是&lt;strong&gt;给具体工具写具体策略&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Git 现在可以在精确授权后执行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add &amp;lt;explicit paths&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git commit -m &amp;lt;message&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git push &amp;lt;remote&amp;gt; &amp;lt;ref&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但 Force Push、Delete Ref、Mirror、Reset/Restore 这类形态仍然直接挡掉。&lt;/p&gt;
&lt;p&gt;Push 如果被批准，也只允许通过固定的非交互 SSH 方式使用当前 SSH Agent，不会顺手把 Credential Helper 或 HTTPS Token 暴露给模型。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gh&lt;/code&gt; 也不是整个二进制一次性放开。&lt;/p&gt;
&lt;p&gt;PR、Issue、Workflow、Release、Merge、Run 都有自己的 bounded shape；&lt;code&gt;gh auth&lt;/code&gt;、&lt;code&gt;gh api&lt;/code&gt;、Secret、Variable、Extension 这些边界仍然封死。&lt;/p&gt;
&lt;p&gt;另外补了不少真实开发里常见的 CLI：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fd / jq
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cmake / ninja
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dotnet / mvn / gradle
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;swift / zig
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pre-commit / act
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo-nextest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Git LFS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;uv / ruff / biome / deno
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker / kubectl / terraform
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我希望最终状态是：&lt;strong&gt;Agent 能正常开发，但“能正常开发”不等于“给它一个 Terminal”。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;tunnel-也不应该因为一个-provider-挂了就不能用&#34;&gt;Tunnel 也不应该因为一个 Provider 挂了就不能用&lt;a class=&#34;heading-anchor&#34; href=&#34;#tunnel-%e4%b9%9f%e4%b8%8d%e5%ba%94%e8%af%a5%e5%9b%a0%e4%b8%ba%e4%b8%80%e4%b8%aa-provider-%e6%8c%82%e4%ba%86%e5%b0%b1%e4%b8%8d%e8%83%bd%e7%94%a8&#34; aria-label=&#34;章节链接：Tunnel 也不应该因为一个 Provider 挂了就不能用&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;wcode 最早的 Remote MCP 默认依赖 Cloudflare Quick Tunnel。&lt;/p&gt;
&lt;p&gt;它很好用，但单 Provider 依赖太脆。&lt;/p&gt;
&lt;p&gt;v0.4 现在的 Auto Path 是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Cloudflare
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↓ fail / missing
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localhost.run
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↓ fail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Pinggy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;后两个直接走 OpenSSH Reverse Forwarding，不需要为了启动 wcode 再自动安装一个 Tunnel Client。&lt;/p&gt;
&lt;p&gt;而且拿到 Public URL 还不算成功。&lt;/p&gt;
&lt;p&gt;Candidate URL 必须真的访问到&lt;strong&gt;当前这个 wcode Runtime 的 instance-matched &lt;code&gt;/healthz&lt;/code&gt;&lt;/strong&gt;，否则不会被当作可用 Tunnel。&lt;/p&gt;
&lt;p&gt;这解决的是一个很现实的问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remote MCP 的网络入口应该是可恢复的基础设施，而不是“某个第三方命令今天能不能跑”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;这次顺手把几个越来越大的文件拆掉了&#34;&gt;这次顺手把几个越来越大的文件拆掉了&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e8%bf%99%e6%ac%a1%e9%a1%ba%e6%89%8b%e6%8a%8a%e5%87%a0%e4%b8%aa%e8%b6%8a%e6%9d%a5%e8%b6%8a%e5%a4%a7%e7%9a%84%e6%96%87%e4%bb%b6%e6%8b%86%e6%8e%89%e4%ba%86&#34; aria-label=&#34;章节链接：这次顺手把几个越来越大的文件拆掉了&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;做性能和 Agent Context 的过程中，有几个文件又开始长得不太舒服：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;main.rs&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;harness.rs&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;Monitor；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;command_policy.rs&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 v0.4 也做了一轮责任拆分。&lt;/p&gt;
&lt;p&gt;现在 Tunnel、Harness Profile、Agent Context、Repo Map、Monitor State 都已经单独落文件。&lt;/p&gt;
&lt;p&gt;发版前最后又把 Command Policy 拆成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;command_policy/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── git.rs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── github.rs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── infrastructure.rs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── dev_tools.rs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我没有为了“模块化”去造新的抽象层，主要目的是别让安全策略继续堆在一个 1500 行文件里。&lt;/p&gt;
&lt;p&gt;这类代码最怕两件事：模型每次要读一大坨上下文，以及多人/多 Agent 修改时冲突越来越集中。&lt;/p&gt;
&lt;h2 id=&#34;mcp-自己也补了一次异常隔离&#34;&gt;MCP 自己也补了一次异常隔离&lt;a class=&#34;heading-anchor&#34; href=&#34;#mcp-%e8%87%aa%e5%b7%b1%e4%b9%9f%e8%a1%a5%e4%ba%86%e4%b8%80%e6%ac%a1%e5%bc%82%e5%b8%b8%e9%9a%94%e7%a6%bb&#34; aria-label=&#34;章节链接：MCP 自己也补了一次异常隔离&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;发版前我碰到过一次很典型的问题：多个 Tool 突然一起报 &lt;code&gt;ExceptionGroup: unhandled errors in a TaskGroup&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;受影响的不只是某一个业务 Tool，&lt;code&gt;workspace_info&lt;/code&gt;、&lt;code&gt;read_file&lt;/code&gt;、&lt;code&gt;run_command&lt;/code&gt;、&lt;code&gt;review_changes&lt;/code&gt; 都会一起失效。&lt;/p&gt;
&lt;p&gt;这个现象说明问题已经不是 Tool 业务逻辑，而是请求隔离边界。&lt;/p&gt;
&lt;p&gt;v0.4 最后补了一层统一的 Request Task Isolation：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP 单请求独立 Task；&lt;/li&gt;
&lt;li&gt;stdio 单请求独立 Task；&lt;/li&gt;
&lt;li&gt;Child Panic / Cancellation / JoinError 转成正常 JSON-RPC Error；&lt;/li&gt;
&lt;li&gt;Durable MCP Task Worker 的 Child Failure 也落成 Task Failure；&lt;/li&gt;
&lt;li&gt;一个 Child 失败以后，后续独立 Tool 仍然可以继续工作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Release Profile 也不再使用 &lt;code&gt;panic=abort&lt;/code&gt;，否则“捕获一个 Child Panic 并保持 Session 可用”在 Release Binary 里根本做不到。&lt;/p&gt;
&lt;p&gt;这个修复对正常路径没有什么新 UI，但我觉得它很重要：&lt;strong&gt;Tool Failure 应该是一次调用失败，不应该升级成整个 Agent Session 坏掉。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;v04-我会怎么概括&#34;&gt;v0.4 我会怎么概括&lt;a class=&#34;heading-anchor&#34; href=&#34;#v04-%e6%88%91%e4%bc%9a%e6%80%8e%e4%b9%88%e6%a6%82%e6%8b%ac&#34; aria-label=&#34;章节链接：v0.4 我会怎么概括&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;如果 v0.3 是“把软件状态接起来”，v0.4 更像是“让这套状态真正适合每天写代码”。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;v0.3&lt;/th&gt;
					&lt;th&gt;v0.4&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Coding Entry&lt;/td&gt;
					&lt;td&gt;多 Tool 组合&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;agent_context&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Context&lt;/td&gt;
					&lt;td&gt;固定/通用&lt;/td&gt;
					&lt;td&gt;Adaptive + Scope-aware&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Repo Map&lt;/td&gt;
					&lt;td&gt;任务时构建&lt;/td&gt;
					&lt;td&gt;Revision Cache + Query Ranking&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Source Read&lt;/td&gt;
					&lt;td&gt;多一步读取&lt;/td&gt;
					&lt;td&gt;Direct Match 可带 Hot Source&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Observatory&lt;/td&gt;
					&lt;td&gt;Requirement-first&lt;/td&gt;
					&lt;td&gt;Architecture-first → Requirement Drill-down&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Command Policy&lt;/td&gt;
					&lt;td&gt;基础安全命令 + Selective Approval&lt;/td&gt;
					&lt;td&gt;Git/GitHub/Dev CLI 的精确 bounded policy&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Tunnel&lt;/td&gt;
					&lt;td&gt;Cloudflare 为主&lt;/td&gt;
					&lt;td&gt;Cloudflare → localhost.run → Pinggy&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Runtime Failure&lt;/td&gt;
					&lt;td&gt;各路径自行处理&lt;/td&gt;
					&lt;td&gt;MCP Request / Child Task Isolation&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Maintainability&lt;/td&gt;
					&lt;td&gt;拆主 Runtime Cluster&lt;/td&gt;
					&lt;td&gt;继续拆 Agent Context / Tunnel / Monitor / Command Policy&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Verification&lt;/td&gt;
					&lt;td&gt;Full Gate&lt;/td&gt;
					&lt;td&gt;Full Gate + 文档 EN/ZH parity regression&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;发版前最后一次本地 Full Gate 是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git diff --check                       ✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo check --locked                   ✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo fmt --check                      ✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo test --locked                    ✅ 210 passed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo clippy --locked -- -D warnings   ✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo build --release --locked         ✅
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Design / Traceability 也还是完整的：Requirement → Component、Design → Implementation、Acceptance → Verification 都是 100%。&lt;/p&gt;
&lt;p&gt;当然，本地绿色只是发版准备；真正的 Release 还是要以 Tagged Revision 和 CI / Release Artifact 为准。&lt;/p&gt;
&lt;h2 id=&#34;最后&#34;&gt;最后&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e6%9c%80%e5%90%8e&#34; aria-label=&#34;章节链接：最后&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.3 的时候我觉得 wcode 真正有意思的地方，是它开始不只关心“代码能不能被 Agent 改”，而是开始关心“软件为什么变成现在这样”。&lt;/p&gt;
&lt;p&gt;v0.4 又让我多了一层判断：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;如果这些 Intelligence 每次都让 Agent 付出很高的上下文和工具往返成本，它最终也不会成为默认工作流。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以这一版看起来没有 v0.3 那么像一次产品方向转弯。&lt;/p&gt;
&lt;p&gt;但对我自己每天用它写代码的体验来说，变化反而更直接。&lt;/p&gt;
&lt;p&gt;现在我希望大部分任务都从一句 Goal 开始，拿到一个足够小但能动手的 Context，然后尽快 Edit、Review、Verify。&lt;/p&gt;
&lt;p&gt;复杂任务再把 Graph、Risk、Reconciliation 拉进来。&lt;/p&gt;
&lt;p&gt;不是让 Agent 每次都理解整个软件世界，而是让它&lt;strong&gt;在需要的时候，拿到刚好足够可靠的那部分。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;代码：&lt;a href=&#34;https://github.com/francis-du/wcode&#34;&gt;https://github.com/francis-du/wcode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;文档：&lt;a href=&#34;https://wcode.francis.run/&#34;&gt;https://wcode.francis.run/&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>wcode v0.3：它已经不只是一个 MCP Bridge 了</title>
      <link>https://francisdu.com/blog/wcode-v0-3/</link>
      <pubDate>Wed, 26 Aug 2026 23:30:00 +0800</pubDate>
      <guid>https://francisdu.com/blog/wcode-v0-3/</guid>
      <description>&lt;p&gt;wcode 的 v0.3 是一次比较明显的方向变化。&lt;/p&gt;
&lt;p&gt;v0.2 发布时，我给它的定位还很简单：一个轻量的 Code Agent plugin，把已经在用的 AI Client 接到本地仓库。&lt;/p&gt;
&lt;p&gt;这个定位没有消失。Remote MCP、OAuth、Workspace、Tree-sitter、代码读写、Git Review 和 Verification 这些底层能力都还在。&lt;/p&gt;
&lt;p&gt;但如果只看 v0.3 的代码和界面，它已经不太像一个“桥”了。&lt;/p&gt;
&lt;p&gt;到 v0.3，我已经不太把它当成一个单纯的“桥”了。模型还是写代码，wcode 开始额外保存设计、变化、风险和验证这些仓库状态。&lt;/p&gt;
&lt;figure class=&#34;content-image&#34;&gt;&lt;img src=&#34;https://francisdu.com/img/wcode/wcode-tui_hu_13e59e78ee0ce797.webp&#34; alt=&#34;wcode 最新终端实时面板&#34;loading=&#34;lazy&#34; decoding=&#34;async&#34; srcset=&#34;https://francisdu.com/img/wcode/wcode-tui_hu_13e59e78ee0ce797.webp 960w, https://francisdu.com/img/wcode/wcode-tui_hu_6437a17a51f06ca3.webp 1800w&#34; sizes=&#34;(max-width: 900px) calc(100vw - 32px), 900px&#34; width=&#34;3420&#34; height=&#34;2146&#34;&gt;&lt;/figure&gt;&lt;h2 id=&#34;v02-当时解决了什么&#34;&gt;v0.2 当时解决了什么&lt;a class=&#34;heading-anchor&#34; href=&#34;#v02-%e5%bd%93%e6%97%b6%e8%a7%a3%e5%86%b3%e4%ba%86%e4%bb%80%e4%b9%88&#34; aria-label=&#34;章节链接：v0.2 当时解决了什么&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;我重新看了一遍 &lt;code&gt;v0.2&lt;/code&gt; Tag 里的 README。&lt;/p&gt;
&lt;p&gt;当时的主线非常明确：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AI Client
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   │ Remote MCP + OAuth
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ▼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ search
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ symbols
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ read / edit
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ project context
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ├─ git review
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └─ verification
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ▼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;configured workspace roots
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一句话就是：&lt;strong&gt;不要再造一个 Agent，把本地代码能力安全地提供给现有 Agent。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;v0.2 已经有不少我现在仍然很看重的基础：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 Rust 原生二进制；&lt;/li&gt;
&lt;li&gt;Remote MCP + OAuth 2.1 / PKCE；&lt;/li&gt;
&lt;li&gt;Cloudflare Quick Tunnel；&lt;/li&gt;
&lt;li&gt;多客户端接入；&lt;/li&gt;
&lt;li&gt;Workspace Root 隔离；&lt;/li&gt;
&lt;li&gt;Tree-sitter Symbol Navigation；&lt;/li&gt;
&lt;li&gt;SHA-256 Guarded Edit；&lt;/li&gt;
&lt;li&gt;Git-aware Review；&lt;/li&gt;
&lt;li&gt;有界并发和实时 TUI。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但它回答的主要还是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;模型怎么安全地碰本地代码？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;v0.3 想回答的问题已经变成：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;多个模型、人和工具不断修改一个项目以后，怎么还知道这个软件为什么是现在这样？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;这版我先把-design-state-接进来了&#34;&gt;这版我先把 Design State 接进来了&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e8%bf%99%e7%89%88%e6%88%91%e5%85%88%e6%8a%8a-design-state-%e6%8e%a5%e8%bf%9b%e6%9d%a5%e4%ba%86&#34; aria-label=&#34;章节链接：这版我先把 Design State 接进来了&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.3 里最重要的东西不是某个新 Tool，而是 &lt;code&gt;.wcode&lt;/code&gt; Design State。&lt;/p&gt;
&lt;p&gt;它把长期应该稳定存在的意图放进仓库：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Requirement
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Component
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Constraint
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Acceptance Criterion
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Decision
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这些东西不是 Markdown 里的描述，而是带稳定 ID 和关系的结构化 Desired State。&lt;/p&gt;
&lt;p&gt;于是一个功能可以真的形成链路：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Requirement
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Component responsibility
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;File / Symbol
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Acceptance Criterion
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Test / Verification
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这也是为什么 v0.3 之后，wcode 不再只是给模型提供 &lt;code&gt;read_file&lt;/code&gt; / &lt;code&gt;apply_edits&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Agent 可以先从需求和设计开始理解，再落到代码。&lt;/p&gt;
&lt;h2 id=&#34;product-scope-把大仓库重新分区&#34;&gt;Product Scope 把大仓库重新分区&lt;a class=&#34;heading-anchor&#34; href=&#34;#product-scope-%e6%8a%8a%e5%a4%a7%e4%bb%93%e5%ba%93%e9%87%8d%e6%96%b0%e5%88%86%e5%8c%ba&#34; aria-label=&#34;章节链接：Product Scope 把大仓库重新分区&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;只做 Design State 还不够。&lt;/p&gt;
&lt;p&gt;仓库一大，Agent 还是很容易把整个项目看成一个平面目录。&lt;/p&gt;
&lt;p&gt;所以 v0.3 有了 canonical Product Scope Registry：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;runtime
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;integrations
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;workspace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;design
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;graph
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;semantics
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;traceability
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;risk
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;verification
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;evidence
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reconciliation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;experience
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;它同时参与源码架构分类、&lt;code&gt;scope_status&lt;/code&gt;、&lt;code&gt;software_context&lt;/code&gt;、MCP Tool Metadata 和 Agent Workflow。&lt;/p&gt;
&lt;p&gt;我现在给 Agent 一个任务时，可以先确定它属于哪个 Product Scope，再缩小上下文。&lt;/p&gt;
&lt;p&gt;这比“先 grep 全仓库再说”稳定很多。&lt;/p&gt;
&lt;h2 id=&#34;software-graph-不再只是一个索引&#34;&gt;Software Graph 不再只是一个索引&lt;a class=&#34;heading-anchor&#34; href=&#34;#software-graph-%e4%b8%8d%e5%86%8d%e5%8f%aa%e6%98%af%e4%b8%80%e4%b8%aa%e7%b4%a2%e5%bc%95&#34; aria-label=&#34;章节链接：Software Graph 不再只是一个索引&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Tree-sitter 仍然是 always-on 的语法底座，但 v0.3 把 Graph 扩成了可以混合多种 Provenance 的 Software Digital Twin。&lt;/p&gt;
&lt;p&gt;基础事实仍明确标注：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;provider = tree-sitter
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;precision = syntax
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果真实 Language Server 返回 Document Symbol、Call Hierarchy 或 Implementation，才会进入 semantic precision。&lt;/p&gt;
&lt;p&gt;外部 SCIP / Compiler / Runtime Provider 也可以进入同一张 Graph，但每条关系都保留自己的 Provider、Precision 和 Revision。&lt;/p&gt;
&lt;p&gt;Graph 现在还会保留 meaningful revision history，可以看节点和关系到底怎么变，而不是只看当前快照。&lt;/p&gt;
&lt;h2 id=&#34;v03-的主界面不是-graph-球图&#34;&gt;v0.3 的主界面不是 Graph 球图&lt;a class=&#34;heading-anchor&#34; href=&#34;#v03-%e7%9a%84%e4%b8%bb%e7%95%8c%e9%9d%a2%e4%b8%8d%e6%98%af-graph-%e7%90%83%e5%9b%be&#34; aria-label=&#34;章节链接：v0.3 的主界面不是 Graph 球图&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;我做过一版能拖、能缩放的 Graph Canvas。&lt;/p&gt;
&lt;p&gt;后来删掉主视图了。&lt;/p&gt;
&lt;p&gt;不是 Graph 没用了，而是“看一团节点”不是我真正想解决的问题。&lt;/p&gt;
&lt;p&gt;现在 WebUI 是 requirement-first 的 &lt;strong&gt;Project Observatory&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Desired State
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Actual State
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Change
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Proof
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Convergence
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一个 Requirement 下面可以直接看到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能意图；&lt;/li&gt;
&lt;li&gt;Component 责任和声明依赖；&lt;/li&gt;
&lt;li&gt;当前真实实现；&lt;/li&gt;
&lt;li&gt;Acceptance / Verification；&lt;/li&gt;
&lt;li&gt;Constraint / ADR；&lt;/li&gt;
&lt;li&gt;当前 Git Change；&lt;/li&gt;
&lt;li&gt;Evidence；&lt;/li&gt;
&lt;li&gt;Convergence Blocker；&lt;/li&gt;
&lt;li&gt;Graph Revision。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;TUI 按 &lt;code&gt;W&lt;/code&gt; 会直接打开当前焦点 Workspace 的 Project Observatory。&lt;/p&gt;
&lt;h2 id=&#34;verification-从跑过测试变成-evidence&#34;&gt;Verification 从“跑过测试”变成 Evidence&lt;a class=&#34;heading-anchor&#34; href=&#34;#verification-%e4%bb%8e%e8%b7%91%e8%bf%87%e6%b5%8b%e8%af%95%e5%8f%98%e6%88%90-evidence&#34; aria-label=&#34;章节链接：Verification 从“跑过测试”变成 Evidence&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.2 已经有 &lt;code&gt;verify_project&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;v0.3 里 Verification 的变化，不是多跑几个命令，而是&lt;strong&gt;结果开始有身份和 Revision&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;现在可以记录：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;谁产生的 Evidence
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;针对哪个 Code Revision
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;针对哪个 Design Revision
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;使用什么 Policy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;结果是 Pass / Fail / Disagree / Inconclusive
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Property、Mutation、Fuzz、Runtime Canary、Blind Reviewer 和 Human Approval 也进入同一套 Verification Mesh。&lt;/p&gt;
&lt;p&gt;最重要的是：新的 Pass 不会把另一个 Producer 的 Fail 擦掉。&lt;/p&gt;
&lt;p&gt;分歧就是 Evidence，而不是需要被 UI 平均掉的噪音。&lt;/p&gt;
&lt;h2 id=&#34;reconciliation-把一次聊天变成可继续的状态&#34;&gt;Reconciliation 把“一次聊天”变成可继续的状态&lt;a class=&#34;heading-anchor&#34; href=&#34;#reconciliation-%e6%8a%8a%e4%b8%80%e6%ac%a1%e8%81%8a%e5%a4%a9%e5%8f%98%e6%88%90%e5%8f%af%e7%bb%a7%e7%bb%ad%e7%9a%84%e7%8a%b6%e6%80%81&#34; aria-label=&#34;章节链接：Reconciliation 把“一次聊天”变成可继续的状态&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.2 的典型开发闭环更像：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;read → edit → test → done
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;v0.3 开始把“什么时候真的算 done”做成显式状态。&lt;/p&gt;
&lt;p&gt;Reconciliation Plan 会把 Drift、Impact、Risk、Implementation 和 Verification Requirement 组织成有依赖的任务。&lt;/p&gt;
&lt;p&gt;这些任务可以 Claim、Submit、Retry，并且持久化。&lt;/p&gt;
&lt;p&gt;所以一个模型写代码、另一个模型 Review、第三个模型补测试，不需要共享同一个聊天上下文。&lt;/p&gt;
&lt;p&gt;它们面对的是同一个软件状态和同一组 Evidence。&lt;/p&gt;
&lt;h2 id=&#34;workspace-权限也比-v02-更细&#34;&gt;Workspace 权限也比 v0.2 更细&lt;a class=&#34;heading-anchor&#34; href=&#34;#workspace-%e6%9d%83%e9%99%90%e4%b9%9f%e6%af%94-v02-%e6%9b%b4%e7%bb%86&#34; aria-label=&#34;章节链接：Workspace 权限也比 v0.2 更细&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.2 的安全模型已经强调：不给模型一个 Shell。&lt;/p&gt;
&lt;p&gt;v0.3 继续保留这个原则，但授权粒度细了很多。&lt;/p&gt;
&lt;p&gt;现在模型如果请求一个还没有授权的裸可执行程序，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flutter
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;deno
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mvn
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gradle
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;wcode 不会因为它不在默认列表里直接永久拒绝，而是生成一个当前 Workspace 的 &lt;code&gt;CommandAccess&lt;/code&gt; Pending Request。&lt;/p&gt;
&lt;p&gt;TUI 会显示待授权列表：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;↑/↓ 选择
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Y    批准当前请求
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;N    拒绝当前请求
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Project Observatory 的 Access Panel 也能处理同一批 Pending Request，并管理 Workspace 和已授权命令。&lt;/p&gt;
&lt;p&gt;批准的是&lt;strong&gt;这个 Workspace 的这个 Program&lt;/strong&gt;，不是开放一个 Shell。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;bash&lt;/code&gt;、&lt;code&gt;sh&lt;/code&gt;、&lt;code&gt;pwsh&lt;/code&gt;、&lt;code&gt;cmd&lt;/code&gt; 这类 Shell Interpreter，以及带路径的 Program Name，仍然是硬边界。&lt;/p&gt;
&lt;p&gt;Repository-aware Argument 还可能再触发单独的 &lt;code&gt;RiskyExecution&lt;/code&gt; 授权。&lt;/p&gt;
&lt;p&gt;删除则仍然更严格：exact one-shot。&lt;/p&gt;
&lt;h2 id=&#34;并发和写入也做了实际性能优化&#34;&gt;并发和写入也做了实际性能优化&lt;a class=&#34;heading-anchor&#34; href=&#34;#%e5%b9%b6%e5%8f%91%e5%92%8c%e5%86%99%e5%85%a5%e4%b9%9f%e5%81%9a%e4%ba%86%e5%ae%9e%e9%99%85%e6%80%a7%e8%83%bd%e4%bc%98%e5%8c%96&#34; aria-label=&#34;章节链接：并发和写入也做了实际性能优化&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;v0.2 已经支持有界并发，但 v0.3 的 Scheduler 已经可以理解 Read / Write / Create / Move / Delete 的路径冲突。&lt;/p&gt;
&lt;p&gt;当前默认全局并行度调整成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;logical CPU × 12
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clamp 96..192
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hard max 256
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同一个文件的多个 &lt;code&gt;apply_edits&lt;/code&gt; 如果 SHA 相同、Range 不冲突，可以先合并再提交。&lt;/p&gt;
&lt;p&gt;另外这次还专门处理了我在真实项目里感觉到的“写代码还是慢”：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;交互式小文件写入保留同目录临时文件 + atomic replace，但不再每次都强制 data fsync + directory fsync；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;project_context&lt;/code&gt; 的 Convention Scan 和 Language Quality Scan 并行执行；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;search_code/search_many&lt;/code&gt; 改成目录遍历过程中直接进入并行搜索，不再先收集完整文件列表；&lt;/li&gt;
&lt;li&gt;多 Edit 共享一次 Line Index；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read_file&lt;/code&gt; 不再先给整个文件分配一份 Line Vector；&lt;/li&gt;
&lt;li&gt;Project Context 会明确让 Agent 优先用 &lt;code&gt;apply_file_edits&lt;/code&gt; / &lt;code&gt;create_files&lt;/code&gt; 做批量写入。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安全边界没有因为这些优化被拿掉：SHA、Atomic Replace、Path Isolation、Symlink / Hardlink、Protected Path 仍然存在。&lt;/p&gt;
&lt;h2 id=&#34;v02--v03我会怎么概括&#34;&gt;v0.2 → v0.3，我会怎么概括&lt;a class=&#34;heading-anchor&#34; href=&#34;#v02--v03%e6%88%91%e4%bc%9a%e6%80%8e%e4%b9%88%e6%a6%82%e6%8b%ac&#34; aria-label=&#34;章节链接：v0.2 → v0.3，我会怎么概括&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;如果只留一张表，大概是这样：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;v0.2&lt;/th&gt;
					&lt;th&gt;v0.3&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;产品中心&lt;/td&gt;
					&lt;td&gt;Local Code Bridge&lt;/td&gt;
					&lt;td&gt;Software Intelligence Runtime&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;模型关系&lt;/td&gt;
					&lt;td&gt;给现有 Agent 本地工具&lt;/td&gt;
					&lt;td&gt;模型是可替换 Builder / Reviewer&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Desired State&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
					&lt;td&gt;Design State&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;源码边界&lt;/td&gt;
					&lt;td&gt;Workspace&lt;/td&gt;
					&lt;td&gt;Workspace + Product Scope&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Code Intelligence&lt;/td&gt;
					&lt;td&gt;Tree-sitter Symbol&lt;/td&gt;
					&lt;td&gt;Composite Software Graph + Provider Provenance&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;改动理解&lt;/td&gt;
					&lt;td&gt;Git Review&lt;/td&gt;
					&lt;td&gt;Drift + Impact + Risk&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;验证&lt;/td&gt;
					&lt;td&gt;Project-native checks&lt;/td&gt;
					&lt;td&gt;Verification Mesh + Revision-exact Evidence&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;长任务&lt;/td&gt;
					&lt;td&gt;普通 Tool Call&lt;/td&gt;
					&lt;td&gt;MCP 2026 Durable Tasks&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;完成状态&lt;/td&gt;
					&lt;td&gt;一次调用结束&lt;/td&gt;
					&lt;td&gt;Reconciliation / Convergence&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;UI&lt;/td&gt;
					&lt;td&gt;TUI + Setup Hub&lt;/td&gt;
					&lt;td&gt;TUI + Setup Hub + Project Observatory&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;授权&lt;/td&gt;
					&lt;td&gt;粗粒度 Trust Flag&lt;/td&gt;
					&lt;td&gt;Pending Request + TUI/WebUI selective approval&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;v0.2 解决的是“把 AI 接进来”。&lt;/p&gt;
&lt;p&gt;v0.3 更像是在回答：“接进来以后，怎么让这个项目长期不失控。”&lt;/p&gt;
&lt;p&gt;我现在觉得这才是 wcode 真正有意思的方向。&lt;/p&gt;
&lt;p&gt;相关实现细节可以继续看 &lt;a href=&#34;https://francisdu.com/blog/wcode-2026/&#34;&gt;wcode 最近做成什么样了&lt;/a&gt;、&lt;a href=&#34;https://francisdu.com/blog/wcode-design-state/&#34;&gt;Design State&lt;/a&gt;、&lt;a href=&#34;https://francisdu.com/blog/wcode-verification/&#34;&gt;Verification&lt;/a&gt;、&lt;a href=&#34;https://francisdu.com/blog/wcode-authorization/&#34;&gt;授权中心&lt;/a&gt; 和 &lt;a href=&#34;https://francisdu.com/blog/wcode-security/&#34;&gt;Security&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;后续的写代码热路径、Agent Context、Architecture-first Observatory 和精确命令策略，继续写在 &lt;a href=&#34;https://francisdu.com/blog/wcode-v0-4/&#34;&gt;wcode v0.4：开始为 Agent 的上下文成本负责&lt;/a&gt;。&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>