Files
dsh_ai1net_server/交付物/新包骨架-S2落地与四尺读数-20260926.md
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 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/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

12 KiB
Raw Permalink Blame History

新包骨架 · 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)

  1. 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】 —— 它既不在文档库也不在工作区, 算法取"末两段"作域键。这是既有算法对新仓库的固有盲区,不是本棒引入的问题。
  2. 非 ASCII 会话名 ⇒ 锁目录名被改写:.locks/插件投放与分库线-40 实际落成 .locks/________________________-40-2147666670(非 ASCII 段→下划线 + cksum 后缀)。 ⇒ 后续棒别按会话名猜目录,要用 ls .locks/ 找。
  3. 🔴 本次抢锁的"结果校验"方式(照纪律:⛔ 不看输出、要看结果):复读 .locks/<实际目录>/OWNER 与 DOMAINS 两个文件并断言归属 —— 未采用 | grep 截尾(那会吃掉退出码,也吃掉"抢不到")。

八、遗留 / 下一棒

# 遗留项 归属
1 浏览器级读数(S2-4) 客户端线起真壳后跑 v-ui.sh;或由下一棒在拿到真壳窗口时补
2 运行面有效读数 同上(需一次含本包的 boot)
3 真机投放(两端各起一次) 撞硬边界「不碰把包装进去」⇒ 归 S4 之后的编排
4 S3 数据面(声明 ⇒ 建库 dshs_pl_ai1net ⇒ 迁移 ⇒ 对账;⛔ 先建库再投放) 下一棒(第 41 棒 · 执行棒)