soia-env-storage-cleanup
先只读统计 SOIA 受管目录,再生成有时效、带摘要的清理计划。删除属于不可逆高风险动作:必须把候选类别、大小、条件和风险展示给客户,等待客户针对这份计划明确授权后,才能执行并复核。
客户可读说明
这个技能可以做什么
| 客户想要 | 技能会做 | 客户能看到 |
|---|---|---|
| 看 SOIA 数据占了多少空间 | 只读统计配置、状态、缓存和临时目录 | 各类别大小、文件数和可清理大小 |
| 判断哪些文件能清理 | 按时效、容量、安全标记和活动状态分类 | 可清理、需授权、禁止清理及原因 |
| 清理过期数据 | 先冻结计划,提醒风险,等待明确授权后按计划删除 | 删除数量、失败项和实际释放空间 |
| 复核清理结果 | 重新检查删除结果和回执摘要 | 是否删除成功、是否有文件重新出现 |
本技能只清理 SOIA 标准受管目录,不扫描或清理整个磁盘,不删除普通下载、项目、照片、文档或其他应用数据。
客户如何使用
客户只需要用自然语言提出目标,不需要操作终端:
- 客户说“检查 SOIA 占用”时,只执行扫描,不删除任何文件。
- 客户说“清理缓存”时,先生成计划并展示风险;这句话只表示目标,不是最终删除授权。
- Agent 必须停下来等待客户在看到最新计划后明确回复,例如“确认按计划
<plan_id>删除”。 - 只有同一份未过期计划获得授权后,Agent 才执行清理;模糊的“继续”“随便处理”不能作为授权。
- 清理完成后重新检查,并向客户报告实际结果。
依赖与安装
| 依赖 | 类型 | 安装 / 配置 | 缺失时怎么处理 |
|---|---|---|---|
| Python 3.10+ | 强依赖 | 使用系统或 soia-env-python-install 提供的 Python |
停止清理,只说明如何补齐 |
soia-env-storage-cleanup |
本技能 | claude plugin install soia-env@soia(或 npx 路线 npx skills add soia-team/soia-open-env-skills -g -a '*' -s soia-env-storage-cleanup -y) |
优先装领域插件;npx 路线会落进共享真源 |
本技能不保存账号或凭据。以下变量只能覆盖受管目录位置,值必须是目录而不是秘密:
SOIA_SKILLS_CONFIG_HOME
SOIA_SKILLS_STATE_HOME
SOIA_SKILLS_CACHE_HOME
SOIA_SKILLS_TEMP_HOME
使用环境变量指定自定义根目录时,必须先向客户展示目标目录并取得配置确认,再写入类别匹配的 .soia-storage-root.json;缺少标记时执行器拒绝把任意目录认领为 SOIA 存储。
WorkBuddy 的装载单位是角色化专家而不是插件,npx skills add -a '*' 覆盖不到它,需要单独安装,见 docs/install/workbuddy.md。
私密信息与中间数据
- 配置目录只统计、不删除;凭据仍由 provider 登录态或系统凭据库管理。
- 清理计划和回执保存在用户 state 目录,使用用户私有权限;不得提交到 Git。
- 计划内部可以保存精确路径用于防止删错,但客户回复只展示脱敏类别、数量和大小。
- 不读取文件正文,不计算内容摘要;状态清理只读取受管策略标记。
- 不把仓库、用户主目录、客户交付物或未知目录认领为可清理目录。
强制授权与风险提醒
扫描、计划和删除是三个独立阶段。初始“帮我清理”请求不能同时授权尚未生成的候选清单。
执行删除前必须向客户显示:
风险提醒:下面的删除不可撤销,可能导致缓存重新下载、审计历史缩短,
或使依赖这些中间文件的任务需要重新运行。配置、凭据和客户交付物不会删除。
请确认是否按计划 <plan_id> 删除 <候选文件数> 个文件,预计释放 <大小>。
只有客户在这条提醒之后明确确认当前 plan_id,才能生成 authorization_id 并调用执行命令。以下情况必须重新扫描并重新授权:
- 计划超过 30 分钟;
- 计划摘要不匹配;
- 候选文件或状态策略发生变化;
- 客户修改清理范围;
- 需要增加新的目录或数据类别。
清理范围和方式
| 数据类别 | 默认条件 | 清理方式 | 风险 |
|---|---|---|---|
| 配置 | 无 | 永不自动清理,只统计 | 禁止清理 |
| 审计状态 | 超过 30 天、100 条或 10 MiB,且技能目录存在允许清理的受管标记 | 客户授权后按过期/最旧顺序删除普通文件 | 高 |
| 缓存 | 超过 7 天,或总量超过 512 MiB | 客户授权后按过期/最旧顺序删除 | 中 |
| 临时文件 | 超过 24 小时且没有活动标记 | 客户授权后删除 | 中 |
无论客户如何授权,以下对象仍必须拒绝:
- SOIA 受管根目录之外的路径;
- 符号链接、设备、socket 和非普通文件;
- 含新鲜
.soia-active标记的活动目录; .soia-active、.soia-managed-storage.json安全标记本身;.soia-storage-root.json根目录标记本身;- 未带有效状态清理标记的 state 文件;
- 文件大小或修改时间在计划后发生变化的候选;
- 配置、凭据和客户交付物。
详细机器合同和标记格式见 清理安全合同。
工作流
1. 只读扫描
Agent 运行:
python3 scripts/storage_cleanup.py scan --json
扫描不得创建目录、计划或回执。把机器输出转换为下面的客户列表,不回显精确私有路径。
2. 生成清理计划
客户要求清理时运行:
python3 scripts/storage_cleanup.py plan --json
计划只能写入受管 state 目录,包含 30 分钟有效期、候选文件元数据和 plan_digest。生成计划仍不代表授权,也不删除文件。
3. 展示计划并等待客户授权
向客户展示:
| 数据类别 | 当前大小 | 可清理大小 | 候选文件 | 清理条件 | 风险 |
|---|---|---|---|---|---|
| <配置/审计状态/缓存/临时文件> | <大小> | <大小> | <数量> | <条件> | <禁止/高/中> |
然后发送强制风险提醒并结束当前执行回合。没有客户新回复,不得进入第 4 步。
4. 按授权计划清理
确认客户明确授权当前计划后,由 Agent 生成不含客户原话的随机 authorization_id,记录授权时间,并运行:
python3 scripts/storage_cleanup.py clean \
--plan <managed-plan-path> \
--plan-digest <plan-digest> \
--confirmed-plan-id <plan-id-confirmed-by-customer> \
--authorization-id <opaque-authorization-id> \
--authorized-at <RFC3339-with-timezone> \
--acknowledge-risk CUSTOMER_APPROVED_IRREVERSIBLE_DELETE \
--execute --json
不得替客户预填授权,不得把 --execute 放进扫描或计划命令。--confirmed-plan-id 必须来自客户在风险提醒后的明确回复,并与计划精确匹配。执行器只删除计划中仍未变化且仍符合条件的普通文件;不确定项进入 skipped。
5. 复核
清理后运行:
python3 scripts/storage_cleanup.py verify --receipt <managed-receipt-path> --json
核对实际删除数量、删除字节数、失败/跳过项、磁盘空闲空间变化和文件是否重新出现。删除命令返回 0 不能代替复核。
客户状态列表(强制)
| 技能 | 当前状态 | 当前版本 | 最新版本 | 运行状态 | 更新时间 | 处理结果 |
|---|---|---|---|---|---|---|
| 存储清理 | <已扫描/等待授权/已清理/被阻塞> | 1.0.0 |
<版本或未取得> | <正常/预警/异常/未验证> | <发现候选/等待客户确认/已释放空间/被阻塞:原因> |
- 只有扫描完成时写“已扫描”;生成计划后写“等待授权”。
- 没有客户针对当前计划的明确授权时,处理结果必须写“等待客户确认”,不能写“已清理”。
更新时间是最后一次扫描或删除复核完成时间,不是技能文件修改时间。
日志与完成回执
客户可见回复只报告:
- 四类受管数据的大小、文件数和候选大小;
- 当前
plan_id、有效期和是否等待授权; - 风险提醒和禁止清理类别;
- 授权后实际删除/跳过数量、删除字节数和复核状态;
- 不显示精确私有路径、文件名、用户名、token 或文件正文。
本地机器回执保存 plan_digest、authorization_id、authorized_at、checked_at、删除结果和 receipt_digest,权限尽量使用目录 0700、文件 0600。
前向测试
至少覆盖以下 fixture:配置文件永不删除;过期 cache/temp 可进入计划;新文件和活动目录不进入计划;state 缺标记时拒绝;符号链接拒绝;错误/过期摘要和缺少授权时阻断;候选在计划后变化时跳过;授权成功后只删除计划内文件并复核回执。
真实机器验收只运行 scan。删除前向测试必须在测试临时目录内完成,不能用真实客户目录验证。