- 变更规模:新增 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/ 知识文件,按口径入库)
155 lines
12 KiB
Markdown
155 lines
12 KiB
Markdown
# 新包骨架 · 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 棒 · 执行棒)** |
|