mirror of
https://git.openapi.site/https://github.com/desirecore/agent-desirecore.git
synced 2026-10-21 04:44:28 +08:00
fix: 限定卸载范围并要求真实核验证据引用 (#14)
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: 应用安装管理
|
name: 应用安装管理
|
||||||
description: 安装、升级、卸载或检查应用;读取固定资料,复用执行工具核验后记录结果。处理 ApplicationManagement 请求;旧服务 RegistryCatalogAcquisition 请求按需读取兼容指南。
|
description: 安装、升级、卸载或检查应用;读取固定资料,复用执行工具核验后记录结果。处理 ApplicationManagement 请求;旧服务 RegistryCatalogAcquisition 请求按需读取兼容指南。
|
||||||
version: "1.5.1"
|
version: "1.5.2"
|
||||||
requiredClientVersion: "10.0.170"
|
requiredClientVersion: "10.0.170"
|
||||||
type: procedural
|
type: procedural
|
||||||
risk_level: high
|
risk_level: high
|
||||||
@@ -36,4 +36,6 @@ Agent 理解环境并执行;已有工具提供能力;Agent Service 只可靠
|
|||||||
5. 超时、断线和结果不明时先观察,不重放有副作用的命令;同一安装同时存在其他修改任务时不并发执行。核验只说明实际检查过的能力。
|
5. 超时、断线和结果不明时先观察,不重放有副作用的命令;同一安装同时存在其他修改任务时不并发执行。核验只说明实际检查过的能力。
|
||||||
6. 结果明确后提交一次带时间的观察,material 必须原样复用成功 resolve 的 data.material(包括 action 与 snapshot);首装结束也不能改成 manage。不预写 installing/reinstalling/uninstalling,不拼装 pending 状态或完整收据,不直接编辑 installed-entries.json。版本必须与本次固定资料一致;发现不同版本应先确认正确资料,不能伪报核验成功。
|
6. 结果明确后提交一次带时间的观察,material 必须原样复用成功 resolve 的 data.material(包括 action 与 snapshot);首装结束也不能改成 manage。不预写 installing/reinstalling/uninstalling,不拼装 pending 状态或完整收据,不直接编辑 installed-entries.json。版本必须与本次固定资料一致;发现不同版本应先确认正确资料,不能伪报核验成功。
|
||||||
7. 记账失败只重读并处理记录,不重复安装/卸载。记录修订冲突要重新观察,不能只换 expectedRevision。异常时按需读取 [恢复原则](references/recovery.md)。
|
7. 记账失败只重读并处理记录,不重复安装/卸载。记录修订冲突要重新观察,不能只换 expectedRevision。异常时按需读取 [恢复原则](references/recovery.md)。
|
||||||
8. 最后说明软件的实际结果与记录是否提交成功;二者可能不同。进度留在当前会话/既有任务;不得承诺无人执行的后续修复或“所有失败都已回滚”。
|
8. 卸载仅移除已核验的应用包/安装目录;不能因为位于同一前缀就递归清理父目录。未知文件、同级数据、凭据和日志默认保留;额外删除必须逐项说明并另获确认。清理空父目录只用非递归删除,非空就保留。
|
||||||
|
9. 证据引用使用工具实际返回的调用 ID、真实会话日志位置或本次已保存的核验报告路径,不编造 session:…:step:… 标识;没有可追溯引用就先保存不含秘密的报告。
|
||||||
|
10. 最后说明软件的实际结果与记录是否提交成功;二者可能不同。进度留在当前会话/既有任务;不得承诺无人执行的后续修复或“所有失败都已回滚”。
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ const body = {
|
|||||||
|
|
||||||
限制:location 最多 2048 字符、不能含换行/NUL;evidenceRefs 1–8 个,每项最多 512 字符;notes 最多 2000 字符。不填 runtimeStatus、operationId、pending 字段或 catalogReceipt。证据引用由 Agent 报告,服务端校验结构和记录一致性,不声称验证引用内容或软件真实安全。
|
限制:location 最多 2048 字符、不能含换行/NUL;evidenceRefs 1–8 个,每项最多 512 字符;notes 最多 2000 字符。不填 runtimeStatus、operationId、pending 字段或 catalogReceipt。证据引用由 Agent 报告,服务端校验结构和记录一致性,不声称验证引用内容或软件真实安全。
|
||||||
|
|
||||||
|
evidenceRefs 不是自由命名的步骤标题。只填实际存在的工具调用 ID、会话日志位置,或已用 Write/执行工具保存的核验报告路径;不能自行编造 `session:…:step:…`。报告保存包版本、实际操作结果和时间,不含凭据;保存失败则如实报告记账前提未满足。
|
||||||
|
|
||||||
成功返回新的 revision、replayed 和当前记录摘要。相同 requestId+相同 body 的当前结果可重复读取,且不重写时间;同 ID 不同 body 拒绝。旧提交已被后续修订取代时,不换 ID/修订强行重提,也不承诺任意历史请求的全局去重。
|
成功返回新的 revision、replayed 和当前记录摘要。相同 requestId+相同 body 的当前结果可重复读取,且不重写时间;同 ID 不同 body 拒绝。旧提交已被后续修订取代时,不换 ID/修订强行重提,也不承诺任意历史请求的全局去重。
|
||||||
|
|
||||||
## 重读和失败
|
## 重读和失败
|
||||||
@@ -55,4 +57,4 @@ const body = {
|
|||||||
|
|
||||||
提交响应丢失:先重读;当前 requestId 相同可用原正文重试。修订变化:观察实际软件再决定是否发起新的核验,禁止只替换 expectedRevision。写入失败:说明软件可能已修改但记录未完成,不重执行安装。具体恢复见 recovery.md。
|
提交响应丢失:先重读;当前 requestId 相同可用原正文重试。修订变化:观察实际软件再决定是否发起新的核验,禁止只替换 expectedRevision。写入失败:说明软件可能已修改但记录未完成,不重执行安装。具体恢复见 recovery.md。
|
||||||
|
|
||||||
应用正常停止后无需改观察记录。卸载默认保留用户数据和凭据;删除这些材料需要独立确认。注册内部服务也属于单独任务,应用安装不派生新的内部 MCP/HTTP 服务。
|
应用正常停止后无需改观察记录。卸载默认保留用户数据和凭据;删除这些材料需要独立确认。先检查实际安装位置及其父目录边界,使用包管理器卸载或只删除已确认归属的应用目录;不得把整个自定义前缀当作可递归删除对象。只检查默认用户数据路径不能证明前缀内没有数据。未知/后来加入的文件一律保留;空父目录可用非递归删除,非空就停止清理。注册内部服务也属于单独任务,应用安装不派生新的内部 MCP/HTTP 服务。
|
||||||
|
|||||||
@@ -666,6 +666,16 @@ test('首装观察示例复用 resolver material,不将 install 改为 manage'
|
|||||||
assert.match(recovery, /响应未知不能如此处理/)
|
assert.match(recovery, /响应未知不能如此处理/)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('卸载不扩大到未知父目录,证据必须实际存在', async () => {
|
||||||
|
const skill = await readFile(skillPath, 'utf8')
|
||||||
|
const api = await readFile(join(here, '..', 'references', 'recording-api.md'), 'utf8')
|
||||||
|
assert.match(skill, /不能因为位于同一前缀就递归清理父目录/)
|
||||||
|
assert.match(skill, /非递归删除,非空就保留/)
|
||||||
|
assert.match(api, /只检查默认用户数据路径不能证明前缀内没有数据/)
|
||||||
|
assert.match(api, /不能自行编造/)
|
||||||
|
assert.match(api, /已用 Write\/执行工具保存的核验报告路径/)
|
||||||
|
})
|
||||||
|
|
||||||
test('Skill contract has no fixed official/local Registry fallback and resolves before execution', async () => {
|
test('Skill contract has no fixed official/local Registry fallback and resolves before execution', async () => {
|
||||||
const skill = await readFile(join(here, '..', 'references', 'legacy-services.md'), 'utf8')
|
const skill = await readFile(join(here, '..', 'references', 'legacy-services.md'), 'utf8')
|
||||||
assert.doesNotMatch(skill, /registry\/official\/entries/)
|
assert.doesNotMatch(skill, /registry\/official\/entries/)
|
||||||
|
|||||||
Reference in New Issue
Block a user