- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次) - .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…), 目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪 - .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/) - .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*) - .gitignore 补:备份件(*.bak-*) - 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
12 KiB
12 KiB
新包骨架 · S2「空包两端落地」执行记录与四尺读数
- 线 / 棒次:插件投放与分库线 · 第 40 棒(执行棒)
- 日期:2026-09-26 | 会话:
插件投放与分库线-40 - 状态:🟡 S2 骨架已落地,装配/取数/回调三面绿;🔴 浏览器级未取到(需客户端线起真壳)
- 唯一执行依据:
05-交接单/交接单_包规格书_20260926.md(§〇 路径约定 / §五 A 冻结规格 / §五 C 指针) +交付物/功能打包到基础插件-分步实施方案-20260926.md§3.10.4(逐步照做唯一权威) - 判据:一律调 S0 四把尺子(
交付物/验证脚本/),退出码即结论:rc=0绿 /rc≠0红 /rc=3未取到(⛔ 3 不是绿)
一、本轮产出
1.1 新包位置与文件清单
包根 = E:/ProgramData/AIProject/dsh-plugin-ai1net/(新建;沿用本机既有插件仓库惯例 dsh-plugin-*,
与 dsh-plugin-carbon / -forge / -partment 同级)
| 文件 | 字节 | 作用 |
|---|---|---|
package.json |
1171 | 包身份 + dsh.bundle.patch(装载补丁)+ dsh.client(浏览器端声明) |
cordis.patch.yml |
954 | 装载声明(insert: { id: ai1net, name: @dsh-local/ai1net }) |
lib/index.js |
8405 | host 半:一条精确路径路由 + 一次事件订阅 |
lib/client.js |
8974 | client 半:lazy-CJS 封包 + 一张骨架卡片 |
scripts/build.mjs |
— | 门禁/组装(零依赖;--check-only 只跑门禁) |
README.md |
— | 包自述(含"两端怎么装它"与自检命令) |
1.2 冻结口径(照规格书 §五 A4,⛔ 未自行改动)
| 项 | 值 |
|---|---|
| 包名 | @dsh-local/ai1net |
| pluginId | ai1net(= 装载条目 id = 配置命名空间) |
| 库名 | dshs_pl_ai1net —— ⚠️ S3 才建,本棒 ⛔ 未碰数据面 |
| 表前缀 | p_ai1net_ —— 同上,本棒 ⛔ 未建表 |
1.3 骨架里只有两件事(⛔ 不写业务)
| 半边 | 内容 | 对应扩展点 |
|---|---|---|
| host | connection.fetch.register({ path:'/api/ai1net/ping', methods:['GET'] }) + settings/document-updated 订阅(骨架占位:只留痕) |
E1(交集内唯一服务端扩展点) |
| client | 挂官方 plugins.item 槽位的一张卡:一句说明 + 一个打探针的按钮 |
E2(dsh.client) |
⚠️ 五个业务模块(多租户 / 模型管理 / 技能插件管理 / 覆盖网络界面 / IM 插件侧)一个都没实现 —— 接口清单仍只在规格书 §五 A3,⛔ 本棒未在代码里预埋任何业务路径。
二、判据读数(原始输出摘要 · 全量见 tmp/p40/尺读数-20260926.txt)
| # | 判据(尺子) | 结果 | 原始证据(摘要) |
|---|---|---|---|
| S2-1a | v-plugin.sh 装配 · 端 A 客户端形态(桌面 profile 实件副本 + 追加本包) |
✅ 绿 rc=0 | ① 声明在 profile bundles:yes(该 profile 共 5 个 bundle)``② 自 profile 目录解析成功:…\dsh-plugin-ai1net\lib\index.js ③ 装载补丁在位:cordis.patch.yml |
| S2-1b | v-plugin.sh 装配 · 端 B 平台形态(profiles/web 键位建模 + dependencies 的 link:) |
✅ 绿 rc=0 | 同上三条;该 profile 共 7 个 bundle(官方 2 + 平台共享层 4 + 本包) |
| S2-2 | v-plugin.sh 取数(真实 import 本产物) |
✅ 绿 rc=0 | exportsOnModule: [PING_PATH, SKELETON_VERSION, apply, inject, name];四条 checks 全 true;verdict: GREEN |
| S2-3 | v-plugin.sh 回调(真实调用 apply(ctx),spy ctx) |
✅ 绿 rc=0 | applyError: null;routeCalls: [{ call:"ctx.connection.fetch.register", args:["{\"path\":\"/api/ai1net/ping\",\"methods\":[\"GET\"]}"] }];onCalls:[{call:"ctx.on", args:["\"settings/document-updated\"","<fn>"]}] |
| S2-3 | 封包契约门禁(node scripts/build.mjs --check-only) |
✅ 绿 rc=0 | 零顶层 import / 零顶层 export / 零顶层 require / 走 __ModuleLoader__ / 交 apply + inject / 零 exports.default(R3);host 半:逐字 inject = ['connection']、零顶层 import、代码零 webServer 引用 |
| S2-4 | v-ui.sh 浏览器级 |
⚠️ 未取到 rc=3 | CDP 端 http://127.0.0.1:9330 不可达 ⇒ 本机当前没有运行中的真壳。⛔ 本线不代启壳(启动器属客户端线) |
| — | v-plugin.sh 运行 |
⚠️ 不成立(不计入绿) | 尺子读到的启动日志 mtime = 2026-09-25T09:19 —— 早于本包存在。本包从未参与该 boot ⇒ "无失败条目"是空真。⛔ 不当证据用(详见 §四) |
S2-3 那条 routeCalls 是本棒最硬的一条证据:它逐字记录了注册的精确路径 /api/ai1net/ping
⇒ 规格书 §五 A2「桌面端只认精确路径、⛔ 无前缀匹配」这条门槛在代码层被真实满足。
三、负控:证明上面那几个绿不是空绿(tmp/p40/负控记录-20260926.txt)
⚠️ S0 的 v-neg.sh 靶子固定为 @dsh-client/portal-first-screen ⇒ 它只证明"尺子能变红",
没有证明"本包的绿不是空绿"。故本棒另做一遍,改坏点只动 tmp/p40/neg/ 里的副本:
| case | 改坏点(单变量) | 改坏后 | 改回原件 |
|---|---|---|---|
| ① 装配 | 从沙箱 profile 的 bundles 里删掉本包那一行 |
rc=1 红 |
rc=0 绿 |
| ② 取数 | inject 去掉 'connection'(就是那个静默 404 的坑) |
rc=1 红 |
rc=0 绿 |
| ③ 回调 | 去掉 ctx.on 订阅 |
rc=1 红 |
rc=0 绿 |
⇒ ✅ 三面负控通过(改坏必红、改回必绿)。
四、如实标注:未取到 / 不成立 / 刻意未做
| 项 | 状态 | 说明 |
|---|---|---|
浏览器级(v-ui.sh) |
⚠️ 未取到 | 需真壳在跑。启动器 …/dsh-ai1net-desktop/.workbuddy/_devkit/launch-desktop-dev-017.mts 属客户端线,本线不代启 ⇒ ⛔ 不折算成"已知"。取数口:在客户端线窗口内起壳后跑 bash 交付物/验证脚本/v-ui.sh。⚠️ 规格书 §3 S2 的完成判据("两端都出现卡片 + JS 错误 0")因此尚未达成。 |
v-plugin.sh 运行 |
⚠️ 不成立 | 见 §二末行。可用日志早于本包 ⇒ 该面无法给出本包的任何信息。须在真壳起来后的新 boot 日志上重取。 |
| 真机投放(两端各起一次) | ⛔ 本棒刻意不做 | 硬边界:⛔ 不碰「起实例 / 取身份 / 把包装进去」三件。本棒只做到"两种形态的 profile 都能解析并装配它"(沙箱建模,见 §五)。 |
dist/ 组装产物 |
⛔ 验证后已移除 | node scripts/build.mjs(全量组装)已跑通 rc=0(产物=4 文件+逐文件 sha256 清单,原始输出在 tmp/p40/组装-full.out)。⚠️ 刻意不留 dist/:lib/ 与 dist/lib/ 是同一份内容的两个副本 ⇒ 造第二个真相源(scripts/build.mjs 自己的文件头就警告这件事),且分发产物的形状应由 S4 定。⇒ 需要时一条命令重建。 |
| 负控用例覆盖 | ⚠️ 3/4 | v-neg.sh 的第四面(运行)依赖真启动日志 ⇒ 与上「运行面不成立」同因,无法在本机形成有效负控。 |
五、"两端"到底指什么(本棒的建模口径 · 冷读者必备)
🔴 "两端"用的不是两套机制,是同一套:两端的装配键本来就是同一个 dsh.profile.bundles。
| 客户端(桌面壳) | 平台侧(实例) | |
|---|---|---|
| profile 位置 | …/home-adapt/profiles/desktop |
<userRoot>/home/profiles/web(profileDirOf(),plugin-assembly.ts:860) |
| 装配键 | dsh.profile.bundles |
同一个键(readProfileManifest(),plugin-assembly.ts:72/75) |
| 包怎么到位 | profile 目录下的 node_modules |
dependencies 写 link: 指向共享只读包库(sharedDirOf()) |
⚠️ 因此本棒的沙箱是"照实件的键位建模",不是真机:
- 端 A = 真桌面 profile
package.json的副本 + 追加本包(⛔ 未动真件 —— 该目录属客户端线 lane, 用户 2026-09-24 明令 + 本棒硬边界「⛔ 不改dsh-desktop-0.1.7rc2的任何文件」); - 端 B = 按
profiles/web的键位手写的沙箱(含平台的link:依赖写法); - 两端的
node_modules/@dsh-local/ai1net= 指向真包的目录软链(= 平台侧link:的落地形态, ⛔ 不是复制)⇒ 尺子量到的就是真产物,不是替身。
⛔ 沙箱只证明"该形态的 profile 能解析并装配本包",不等于"真机上已装好"。
六、硬边界自查
| 边界 | 自查 |
|---|---|
| ⛔ 不改官方 dsh 主程序与缓存(R2) | ✅ 未触碰 |
| ⛔ 不重造分发与更新机制 | ✅ 未动平台侧拉取器/对账;README 与 cordis.patch.yml 只指向既有协议(plugin-assembly.ts),⛔ 未复制其实现 |
| ⛔ 不碰「起实例 / 取身份 / 把包装进去」三件 | ✅ 未起实例、未取身份、未向任何实例投放;只做了沙箱 profile 的解析面 |
⛔ 不改客户端工作区 dsh-ai1net-desktop / dsh-desktop-0.1.7rc2 任何文件 |
✅ 只读;端 A 的 profile 副本落在 tmp/p40/(真件的 mtime 未变) |
| 🔴 红线门禁(重启控制面 / 中断在线用户 / 批量 >10 文件 / 不可逆) | ✅ 均未触发 —— 未 ssh、未部署、未改任何生产文件;本棒新增 6 个文件(全在新包内)+ tmp/p40/ 若干 |
| 🔴 停点:S4 前必停(P1 已于 13:30 拍板)|S9 的 P2 仍待拍板 | ✅ 本棒在 S2,⛔ 未跨过任何停点 |
七、机制层观察(⛔ 未改任何跨库脚本 —— 属机制层须独占,R7/§6)
preflight-lock.sh对 7 个目标路径全判【D】未归类 ⇒rc=1拒开工。 判决与本棒目标全不匹配(本棒压根不在它的ok_files覆盖范围内)⇒ 按第 26–40 棒既有惯例, 用 guard 锚点算法自定域键后开工,⛔ 未改那个跨库脚本(改它就是机制层独占动作,须单独排)。- 实际自定域键(10 个,guard 已复读确认):
aliyun-dsh-server/接续入口_插件投放与分库线_20260922.md|aliyun-dsh-server/.workbuddy|aliyun-dsh-server/交付物|aliyun-dsh-server/tmp|dsh-plugin-ai1net/package.json|dsh-plugin-ai1net/readme.md|dsh-plugin-ai1net/cordis.patch.yml|lib/index.js|lib/client.js|scripts/build.mjs - ⚠️ 新包目录(
dsh-plugin-ai1net/**)在 preflight 里必然落【D】 —— 它既不在文档库也不在工作区, 算法取"末两段"作域键。这是既有算法对新仓库的固有盲区,不是本棒引入的问题。
- 实际自定域键(10 个,guard 已复读确认):
- 非 ASCII 会话名 ⇒ 锁目录名被改写:
.locks/插件投放与分库线-40实际落成.locks/________________________-40-2147666670(非 ASCII 段→下划线 +cksum后缀)。 ⇒ 后续棒别按会话名猜目录,要用ls .locks/找。 - 🔴 本次抢锁的"结果校验"方式(照纪律:⛔ 不看输出、要看结果):复读
.locks/<实际目录>/OWNER与DOMAINS两个文件并断言归属 —— 未采用| grep截尾(那会吃掉退出码,也吃掉"抢不到")。
八、遗留 / 下一棒
| # | 遗留项 | 归属 |
|---|---|---|
| 1 | 浏览器级读数(S2-4) | 客户端线起真壳后跑 v-ui.sh;或由下一棒在拿到真壳窗口时补 |
| 2 | 运行面有效读数 | 同上(需一次含本包的 boot) |
| 3 | 真机投放(两端各起一次) | 撞硬边界「不碰把包装进去」⇒ 归 S4 之后的编排 |
| 4 | S3 数据面(声明 ⇒ 建库 dshs_pl_ai1net ⇒ 迁移 ⇒ 对账;⛔ 先建库再投放) |
下一棒(第 41 棒 · 执行棒) |