一键导入
state-scanner
项目状态扫描与智能工作流推荐,十步循环的统一入口。 收集项目状态、分析变更、推荐最佳工作流、引导用户确认执行。 使用场景:"查看项目当前状态"、"我要提交代码"、"开发新功能"
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
项目状态扫描与智能工作流推荐,十步循环的统一入口。 收集项目状态、分析变更、推荐最佳工作流、引导用户确认执行。 使用场景:"查看项目当前状态"、"我要提交代码"、"开发新功能"
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Aria 项目级配置加载器(内部基础设施)。 查找、解析、验证 .aria/config.json 并合并默认值。 此 Skill 不直接触发,由其他 Skills 引用以读取项目配置。
会话收尾 —— 在任意对话(含未走完十步循环的探索/调试/讨论 session)把"未交接成果" 固化为 handoff。**与十步循环正交平级的会话仪式**(非周期收尾): AI 先内省本对话出 未完成线程 + 待固化经验, 再用机械 autofill 交叉核验补漏, 写 docs/handoff/。leaf — 终结于写交接, 不拖入十步循环。 使用场景: "对话收尾" / "执行对话收尾" / "会话收尾" / "session closeout" / "收尾这次对话" / "写交接" / "写 handoff" / "收工" / "结束本次对话" / context 快满时主动收尾。 不适用 (用 phase-d-closer): "Phase D" / "周期收尾" / "归档 Spec" / "更新 cycle 进度" —— 那是开发周期收尾, 不是会话收尾。
Git 多远程 parity 检测与 push 验证的共享基础设施。 内部工具, 仅供其他 skills 引用。提供标准化 Bash/Python 执行脚本段 + 输出 JSON schema 契约。
任务到 Agent 的智能路由器,根据任务类型、文件路径自动选择最合适的 Agent。 使用场景:subagent-driver 需要为任务选择 Agent、不确定应该使用哪个 Agent
向 Aria 维护团队报告 Bug 或提交功能建议。自动收集环境信息, 自动路由到 Forgejo(内部用户)或 GitHub(外部用户)。 使用场景:"报告 bug"、"report an issue"、"提交功能建议"、 "aria 有个问题想反馈"、"feature request"、"提 issue"、 "反馈问题"、"report bug to aria"
十步循环 Phase B - 开发阶段执行器,编排 B.1-B.3 步骤。 使用场景:"执行开发阶段"、"Phase B"、"创建分支并运行测试"
| name | state-scanner |
| description | 项目状态扫描与智能工作流推荐,十步循环的统一入口。 收集项目状态、分析变更、推荐最佳工作流、引导用户确认执行。 使用场景:"查看项目当前状态"、"我要提交代码"、"开发新功能" |
| argument-hint | [intent] |
| disable-model-invocation | false |
| user-invocable | true |
| allowed-tools | Read, Glob, Grep, Bash |
版本: 3.0.0 | 角色: 十步循环统一入口 机械化: v3.0.0 起 Phase 1.x 由
scripts/scan.py(stdlib-only Python) 机械产出 JSON snapshot, AI 读 snapshot 进入阶段 2 推荐。v2.x prose 路径保留mechanical_mode=falseopt-out, 计划下一 minor (v1.19.0+) 移除 (AD-SSME-5;v1.18.0 ship 时仍保留 — 监测使用量后决定)。
使用场景:
不使用场景:
| 功能 | 描述 |
|---|---|
| 状态感知 | 收集 Git 状态、UPM 进度、OpenSpec 状态、审计状态、自定义检查、变更分析 |
| 智能推荐 | 基于状态生成工作流推荐,附带理由说明 |
| 用户确认 | 展示选项,让用户确认或自定义工作流 |
| 工作流启动 | 将确认的工作流传递给 workflow-runner 执行 |
执行前读取 .aria/config.json,缺失则使用默认值。参见 config-loader。
| 字段 | 默认值 | 说明 |
|---|---|---|
state_scanner.confidence_threshold | 90 | 置信度阈值 (0-100) |
state_scanner.auto_execute_enabled | false | 高置信度自动执行 |
state_scanner.auto_execute_rules | ["commit_only", "quick_fix", "doc_only"] | 允许自动执行的规则 |
state_scanner.audit_log_path | ".aria/audit.log" | 审计日志路径 |
state_scanner.mechanical_mode | true | v3.0.0+: true 走 scan.py 路径, false 回退 v2.x prose 路径 (计划 v1.19.0+ 移除, v1.18.0 ship 时仍保留) |
state_scanner.issue_scan.platform_hostnames.forgejo | ["forgejo.10cg.pub"] | v1.30.0+: Forgejo hosts 可通过 ARIA_FORGEJO_HOSTS env var (comma-separated) 覆盖, 优先级 env > config > default; 同时影响 forgejo_config 和 issue_scan 两 collector (per OpenSpec aria-forgejo-hosts-parameterization) |
workflow.auto_proceed | false | Phase 间自动推进 |
不可协商: Phase 1 所有字段由
scripts/scan.py机械采集, AI 不得跳过 / 不得逐字段手工 Bash 替代 / 不得在失败时"降级"到手工采集。
执行命令:
python3 "${CLAUDE_PLUGIN_ROOT:-aria}/skills/state-scanner/scripts/scan.py" \
--output .aria/state-snapshot.json
退出码契约 (详见 state-snapshot-schema.md §Exit code consumer contract):
| 退出码 | 含义 | AI 动作 |
|---|---|---|
| 0 | 全部采集成功 | 读 .aria/state-snapshot.json, 进入阶段 2 |
| 10 | 部分采集软错误 (snapshot 仍可用, 见 errors[]) | 读 snapshot, 对受影响子阶段展示 warning, 继续阶段 2 |
| 20 | 硬前置失败 (非 git repo / 输出路径写入失败) | abort, 不读 snapshot, 展示 stderr |
| 30 | 未捕获异常 (scan.py 内部 bug) | abort, 展示 stderr, 提示 report bug |
Schema 版本契约: snapshot 顶层 snapshot_schema_version 当前 "1.0", 采用 additive-only 演进 (新字段兼容, 删/改字段需 bump). 详见 state-snapshot-schema.md §Versioning。
AI 禁区 (v3.0.0 机械化契约):
| 行为 | 允许 |
|---|---|
用 git status / ls openspec/ 等命令逐字段采集替代 scan.py | ❌ 不允许 |
| scan.py 失败时手工 Bash 补齐 snapshot (绕过 Phase 1.11/1.13 opt-in) | ❌ 不允许 |
| scan.py 成功后读取 snapshot 引用的外部文件 (audit report 原文 / Story body 细节) | ✅ 允许 |
| Phase 3 展示 / Phase 4 传递给 workflow-runner 走 prose 路径 | ✅ 允许 (这些不是数据采集) |
Opt-out (过渡期): .aria/config.json 设 state_scanner.mechanical_mode=false → 回退 v2.x prose 路径. 该 flag 计划下一 minor (v1.19.0+) 移除 (AD-SSME-5);v1.18.0 ship 时仍保留, 期间零告警使用量 = 安全移除信号。
collectors/interrupt.py)详细逻辑见 interrupt-recovery.md | 状态格式见 workflow-state-schema.md
snapshot 字段: interrupt (含 .aria/workflow-state.json 解析结果, git_anchor.branch 验证, 并发冲突检测).
AI 负责: 根据 interrupt.status 值:
none / 文件缺失 → 直接进入阶段 2 推荐in_progress / suspended → 展示 [1]Resume [2]Abandon [3]Inspect; Resume → workflow-runner(resume=true), Abandon → 提示删 .aria/workflow-state.json 后进阶段 2, Inspect → 展示 interrupt.context 后回选择failed → 展示 [1]Retry [2]Abandon [3]Inspectgit 操作感知 (Aria #135, v1.39.0+, 与 interrupt 正交): snapshot 另有 git.git_operation_in_progress 字段 (collectors/git.py 采集), 检测暂停中的 git 层操作 (operation ∈ {none, rebase, merge, cherry_pick, revert, bisect} + has_conflicts)。这与 interrupt.status 正交、互不篡改 —— interrupt 只看 .aria/workflow-state.json, 检测不到 git 中间态 (rebase 暂停态 detached_head 仍为 False)。operation != "none" 时, 阶段 2 由 git_operation_in_progress 规则 (priority 0.5, 见 RECOMMENDATION_RULES.md) 降级/阻止含 checkout·分支操作的常规推荐, 引导先 git <op> --continue/--abort (has_conflicts=true 措辞升级)。绝不代用户操作 git。
scan.py 按顺序执行 Phase 0.5 + 15 个 collector 子阶段, 每个产出 snapshot 一个固定顶层字段
(remote_refresh (Phase 0.5, F3′, main spec state-scanner-stale-refs-false-parity — 跑在最前面, 新鲜度信号唯一生产者) / git / upm / changes / requirements / openspec / architecture / readme / standards / audit / custom_checks / sync_status / issue_status (opt-in) / forgejo_config / handoff / handoff_worktrees (Step 1.15b, #139 cross-worktree discovery) / coordination_fetch (Step 1.16, multi-terminal — F6′ 起为纯派生 shim, 零独立 I/O, 读 remote_refresh 的 (".", "origin") leg) / tracks_multibranch (Step 1.17, multi-terminal) + errors[] 聚合)。
Opt-in 子阶段: 1.11 custom_checks (需 .aria/state-checks.yaml) / 1.13 issue_scan (config flag)。
1.12 sync_check 不是 opt-in — 恒开启不可关闭 (F9′ 9.2 修正: sync.py 从未读取
state_scanner.sync_check.*, 历史文档"可关闭"的说法与代码不符; 该 collector 承载 US-008
方向性数据丢失护栏, 设计上不允许关闭)。
F6′ 可关闭性契约 (remote_refresh, D16 registered): remote_refresh 目前没有独立的
enable/disable 配置门 (与 issue_scan 不同; sync_check 同样无真实开关, 见上) —— 它由 state_scanner.multi_remote.enforced_remotes
间接控制覆盖范围, enforced_remotes 解析为空集合 (无 remote 可 fetch, 或全部 no_matching_remote)
时 remote_refresh.legs == []。若采用者未来加装独立开关关闭它 (或 legs 为空), 下游必须
遵守这条不变量: remote_refresh 关闭/无 leg ⇒ 所有 remote 的 evidence_grade 落 expired
(fail-CLOSED 默认, _leg_evidence_grade 在 leg=None 时的语义) ⇒ 所有 parity=="equal" 被
_apply_freshness_downgrade 降级为 unknown/not_refreshed ⇒ overall_parity 恒为 false
—— 绝不允许"关掉新鲜度信号生产者"反而让下游因为"零输入"而误判为已同步 (QA-C1 不变量: 零证据不得
当正证据)。该不变量已在 multi_remote.py::_read_remote_refresh_cache docstring 写死
("we have no cache" 与 "we have a cache saying never-fetched" 必须产出同一判决)。
完整 collector 子阶段表 + opt-in 配置 + Step 0.5/1.16/1.17 detail + 子阶段深度参考链接 + TASK-005/006 design decision notes: 见 references/phase-1-collectors.md。
字段定义 source-of-truth: references/state-snapshot-schema.md (remote_refresh 为真 SOT; evidence_grade/overall_parity F4′ 精确定义见该文档 §multi_remote)。
gitlink_integrity[] (Phase 2A, F10″/D14): sync_status.multi_remote.gitlink_integrity 是 multi_remote collector 新增的 per-(R,S) 字段 — R 遍历主仓 enforced remote, S 遍历全部已声明子模块路径 (含未 init 的), 检测「主仓在 R 上已发布的 commit 引用的子模块 gitlink, 在该子模块的 R 上是否可达」。9 分支状态 (ok/orphaned/orphan_unverified/no_published_ref/not_a_gitlink/uninitialized/no_matching_remote/shallow_unverifiable/soft_error) + status 表见 schema 文档。orphaned 恒阻断 overall_parity (clause 3); orphan_unverified 需连续 k_eff 次未验证才升级阻断 (D18)。零子模块的仓库该字段恒 [], 不额外付出任何 git 调用。
P2 Layer L 已 ship (TASK-010~022, 108 tests PASS)。DEC-20260704-002 完成了母 spec 从未落地的 TASK-024 集成 —— run_gate() 从死代码 (零生产调用) 接活成 advisory 认领: AI 编排层 (本 skill 阶段 2 / Phase B-entry) 首次成为 run_gate 的调用者。
接线点 = AI 编排层, 不是 scan.py (layer-l-integration.md:15 Design A: 闸门仅在用户确认进 Phase B 时调用, 不在只读 collector 内自动跑)。触发条件 (默认开启, opt-out — coordination-claim-lifecycle-and-overlap Part A1 把默认 false→true): state_scanner.coordination.enabled == true (缺省即 true) 且 tracks_multibranch.collision.kind 非空 (cross-owner / self_multi_container)。
调用时序:
scan.py → snapshot (含 tracks_multibranch.collision.kind)
→ 阶段 2 推荐: AI 读 collision.kind + 读最新 handoff §6 选定 carry-id (raw_track_id)
→ 用户确认进入 Phase B (phase-b-developer B.1 / branch-manager)
→ AI 编排层经 subprocess 调 phase1_gate CLI (Phase B 启动前, 对齐 :44):
python3 "${CLAUDE_PLUGIN_ROOT:-aria}/skills/state-scanner/scripts/phase1_gate.py" \
--raw-track-id "<§6 选定 carry-id 原始串>" --phase B --mode advisory --repo-path "<repo root>"
→ 解析 stdout JSON (GateResult projection); exit 0 = 可进 Phase B
--raw-track-id; 归一 (derive_track_id) 在 run_gate 内部完成, 编排层不预归一 (R1-m6)。carry-id 来源 = handoff §6 结构化 {id, desc} (见 standards/conventions/session-handoff.md §2.3)。state_scanner.coordination.mode 决定 (默认 advisory)。advisory = 放行 + 写推自己 claim + 返回 surface 告警 (advisory-over-hardlock); reconcile 仍是最终仲裁 (earliest claimed_at 胜)。mode=block 经 CLI 退化为安全默认 abort (已知限制, 生产默认 advisory)。CLI 输出 {outcome, proceed, track_id, error, own_claim, competing_winner, surface, push_success}。渲染规则:
proceed == true (outcome ∈ passed / advisory_proceed / user_takeover / user_override_proceed) → 放行进 Phase B。surface != null → 在推荐区渲染 🔴 告警行 (按 surface.kind 分化, 不 blanket 静默 R2-Major-B):
kind == "occupied" → 🔴 surface.message (含 <owner/container> <age> 已认领 <carry-id>), 回显 surface.carry_id 供逐字 copy (R1-m5, 减少转录漂移)。kind == "clock_skew" → 🔴 surface.message (含 max_clock_skew_seconds) —— 最高风险路径, 提示查容器时钟同步; advisory 不吞 此告警。kind == "push_failed" → 🔴 claim 已写本地未同步远端, reconcile 下次 fetch 仲裁。enabled == false (显式 opt-out; Part A1 起默认为 true) → 零调用 run_gate, collision 由 rule 1.54 advisory surface。claim 生命周期闭环 (coordination-claim-lifecycle-and-overlap Part C): acquire (phase1_gate, Phase B-entry) 的对偶是 release (scripts/release_gate.py, phase-d-closer D.2b 收尾时调, 按 track_id+container 定位 — session 无关) + --sweep-stale (heartbeat 超 STALE_TTL 的 active → abandoned) + --gc (done 超 retention → archive/)。phase1_gate 另支持可选 --linked-issue (Part B1): 写入 claim 并在输出 JSON 追加 additive 键 linked_issue_overlap[] — 同 issue 不同 track-id 的「同一件事两个名字」advisory 告警, 渲染为 🔴 提示但不阻断。
完整设计意图 (phase1_gate 9-step 序列 / acquire_claim+heartbeat+release 调用关系 / advisory outcome 映射 / track_board+latest_md_writer 输出): 见 references/layer-l-integration.md。
阶段 2 = 推荐决策 (snapshot 入口断言 + 推荐规则匹配 + audit 集成 + handoff awareness mandatory [H0 spec 防 4 起历史 bug] + inter-cycle resume sanity check)。 阶段 3 = 用户确认 ([1]-[4] 编号选项 + 自定义组合, auto_proceed 仅 ≥90% confidence 触发)。 阶段 4 = 工作流启动 (输出 workflow + context 给 workflow-runner, 含 complexity_level for adaptive audit)。
完整流程 (阶段 2 入口断言 + 推荐规则类别 + audit 集成 + handoff awareness 3-branch logic + inter-cycle sanity check / 阶段 3 用户确认 / 阶段 4 workflow-runner 输出 schema + adaptive 集成): 见 references/recommendation-stages.md。
推荐输出含以下 10 个 canonical 区块 (按顺序)。每区块只在数据可用时显示, 空状态优雅降级。下方骨架给出每区块的关键字段, 使「不读 reference 也能正确排版到字段层」成立 (#72: 仅列区块名会致字段层漂移)。完整字段措辞 / 各漂移变体仍以 references/output-formats.md 为准。
design_deferred[] 非空时: ⚠️ N 个 — id + status + staleness_days, #134 v1.42.0+)issue_scan.enabled=true 显示另有条件块在特定场景插入 (见 output-formats.md): 🔬 Skill 变更 AB 状态 (检出 SKILL.md 变更时) / handoff awareness (Phase 1.15, handoff doc surfaced 或 drift) / 🌲 跨 worktree 交接 (Phase 1.15b, #139,
handoff_worktrees.global_latest_elsewhere为 active 时)。
完整标准输出示例 + 各场景输出变体 (未配置、链路不完整、待归档、头脑风暴建议等): 见 references/output-formats.md。
| 参数 | 必需 | 说明 | 示例 |
|---|---|---|---|
intent | ❌ | 用户意图 (影响推荐) | "提交代码", "开发功能" |
module | ❌ | 目标模块 (自动检测) | mobile, backend |
skip_recommendation | ❌ | 跳过推荐直接扫描 | true, false |
用户: "我要提交代码"
state-scanner 执行:
Step 0: python3 scripts/scan.py --output .aria/state-snapshot.json
阶段 2: 读 snapshot, changes.file_types=[code, test] + openspec add-auth=approved
→ 匹配 feature_with_spec 规则
阶段 3: 展示推荐 feature-dev, 等待确认
阶段 4: 用户选 [1], 调 workflow-runner
输出到 workflow-runner:
workflow: feature-dev
skip_steps: [A.1, A.2, A.3, B.3]
用户: "只运行测试和提交"
state-scanner 执行:
Step 0: scan.py 产出 snapshot
阶段 2-3: 展示推荐
用户: "B.2 + C.1"
输出到 workflow-runner:
workflow: custom
steps: [B.2, C.1]
用户: "查看项目状态"
输入: skip_recommendation: true
state-scanner 执行:
Step 0: scan.py 产出 snapshot
阶段 1: 展示 snapshot 摘要 (format 见 output-formats.md)
结束,不调用 workflow-runner
详细推荐规则 (优先级、条件、自定义扩展) 见 RECOMMENDATION_RULES.md。
state-scanner v3.0 (本 Skill)
│
│ Step 0: scan.py → snapshot.json
│ 阶段 2-4: 推荐 + 用户确认
▼
workflow-runner v2.0
│
├──▶ phase-a-planner (A.1-A.3)
├──▶ phase-b-developer (B.1-B.3)
├──▶ phase-c-integrator (C.1-C.2)
└──▶ phase-d-closer (D.1-D.2)
重要: Claude Code 在 Windows 上使用 Git Bash/WSL。scan.py 是 stdlib-only Python, 本身跨平台兼容; AI 辅助命令 (展示 / 文件读取) 仍需遵循跨平台语法。
| ✅ 正确 | ❌ 错误 |
|---|---|
ls path/*.md 2>/dev/null || echo "NO" | if exist path\*.md (dir ...) else (echo NO) |
ls docs/requirements/ | dir docs\requirements\ |
[ -f file ] && cat file | if exist file (type file) else ... |
路径使用 / | 路径使用 \ |
2>/dev/null | 2>nul |
详细的跨平台命令示例和调试技巧,见 references/cross-platform-commands.md。
_normalize_status 归一化 11 个 lifecycle state (archived / deprecated / pending / in_progress / implemented / approved / reviewed / active / ready / done / unknown), 驱动 pending_archive / requirements / 推荐规则。首段截断规则 (aria-plugin #50): em-dash 后 narrative 不参与归类。
完整 token set 表 / 推荐 Status 格式 / 首段截断分隔符规则 / Anti-pattern substring shadows / Implementation note: 见 references/status-field-guide.md。
| 错误 | 原因 | 解决方案 |
|---|---|---|
| scan.py exit 20 | 非 git repo / 输出路径写入失败 (硬前置失败) | 根据 stderr 提示修复, 重跑 |
| scan.py exit 30 | 未捕获异常 (scan.py 内部 bug) | 收集 stderr 提交 issue, 临时 opt-out mechanical_mode=false |
| snapshot 文件缺失 | Step 0 未执行或被中断 | 重跑 /state-scanner |
| snapshot_schema_version 不匹配 | scan.py 与 SKILL.md 版本漂移 | 升级 aria-plugin 至匹配版本 |
| 推荐冲突 | 多规则同时匹配 | 按优先级选择第一个 (见 RECOMMENDATION_RULES.md) |
| Bash 语法错误 (辅助命令) | 使用了 Windows CMD 语法 | 参考跨平台命令规范 |
最后更新: 2026-05-22 (state-scanner-status-extraction-range #50: _status 首段截断 + delivered/shipped token + soft_error)
Skill版本: 3.1.1 (2026-05-22: _status_lifecycle_head 首段截断修复 aria-plugin #50 — 长单行 Status token shadow;3.1.0: 2026-05-09 inter-cycle-surfacing G2/G3/G4 — 见 v1.18.0 CHANGELOG)