两次独立的真实进程取证(PM 会话与 objectui#7177 的 dev,各自的 os dev 启动)都撞到同一现象,先记录待 triage,不预设修法。
实测
examples/app-todo,os dev --seed-admin,登录后:
POST /api/v1/packages/com.example.todo/duplicate {"targetPackageId":"com.acme.dupbase","targetName":"Dup Base"}
→ HTTP 200
{"success":true,"data":{"success":false,"copiedCount":0,"failedCount":0,"targetPackageId":"com.acme.dupbase","copied":[],"failed":[]}}
为什么值得一张卡
packages/rest/src/package-routes.ts:816-818 与 objectui packages-io.ts 的注释都把 duplicate 描述为 ADR-0070 D4 的「duplicate base」手势:只读的代码包由此变成可定制的起点,对象重命名空间、包内引用服务端重写。如果对代码包的对象本就不拷(只拷 sys_metadata 里的 DB 行),那这条手势对它的主要用例是空的,文档与实现至少有一方不对;如果本该拷,那就是缺陷。两种结论都需要一个 pin:对一个启动中的代码包 duplicate 后 copiedCount 等于其对象数(或明确的 422 拒绝,说明该手势只适用于 DB base)。
不做的事
不在 objectui 侧绕:客户端已经按 EMPTY 臂正确报错,问题在服务端语义。
两次独立的真实进程取证(PM 会话与 objectui#7177 的 dev,各自的
os dev启动)都撞到同一现象,先记录待 triage,不预设修法。实测
examples/app-todo,os dev --seed-admin,登录后:com.example.todo是启动中的代码包(registerApp注册,scope:'project'),带 1 个对象、4 个 flow、视图、仪表盘、报表。GET /api/v1/packages里出现com.acme.dupbase(无scope键、writable:true),detail 门 200。copied:[]、failed:[]——这是 objectuidescribeDuplicateFailure文档里写明的 EMPTY 臂("nothing was copied … rows may be outside this caller's scope")。manifest里还嵌了一份源包的manifest(manifest.manifest.id === 'com.example.todo')——复制的是摊平后的源 bundle。GET /api/v1/packages//api/v1/packages/:id//api/v1/meta/package全部 500「Converting circular structure to JSON」—— 栈里带插件实例(showcase)时,包记录存的是含实例的原始摊平 bundle #14442 的循环引用在sys_packages持久化处直接失败,无法对照。为什么值得一张卡
packages/rest/src/package-routes.ts:816-818与 objectuipackages-io.ts的注释都把 duplicate 描述为 ADR-0070 D4 的「duplicate base」手势:只读的代码包由此变成可定制的起点,对象重命名空间、包内引用服务端重写。如果对代码包的对象本就不拷(只拷sys_metadata里的 DB 行),那这条手势对它的主要用例是空的,文档与实现至少有一方不对;如果本该拷,那就是缺陷。两种结论都需要一个 pin:对一个启动中的代码包 duplicate 后copiedCount等于其对象数(或明确的 422 拒绝,说明该手势只适用于 DB base)。不做的事
不在 objectui 侧绕:客户端已经按 EMPTY 臂正确报错,问题在服务端语义。