소스 정보
- 저장소
- 10CG/aria-plugin
- 최근 소스 활동
- 2026년 8월 22일 22:47
- 감지된 SKILL.md 언어
- 다국어 혼합
- 스타
- 1
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/10CG/aria-plugin --skill phase-c-integrator명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
项目状态扫描与智能工作流推荐,十步循环的统一入口。 收集项目状态、分析变更、推荐最佳工作流、引导用户确认执行。 使用场景:"查看项目当前状态"、"我要提交代码"、"开发新功能"
Aria 项目级配置加载器(内部基础设施)。 查找、解析、验证 .aria/config.json 并合并默认值。 此 Skill 不直接触发,由其他 Skills 引用以读取项目配置。
十步循环轻量编排器,协调 Phase Skills 执行,支持灵活组合。 使用场景:"执行 quick-fix 工作流"、"运行 [Phase B, Phase C]"、自定义 Phase 组合
SKILL.md 표시 중
| name | phase-c-integrator |
| description | 十步循环 Phase C - 集成阶段执行器,编排 C.1-C.2 步骤。 使用场景:"执行集成阶段"、"Phase C"、"提交代码并创建 PR" |
| argument-hint | [--skip-pr] |
| disable-model-invocation | false |
| user-invocable | true |
| allowed-tools | Bash, Read, Write, Glob, Grep, Task, Skill |
版本: 1.3.0 | 十步循环: C.1-C.2 更新: 2026-05-10 - C.2.4 Pre-Merge Precondition Gate (#60, consume aether
--in-flightprimitive) 历史更新: 2026-03-27 - 升级审计触发从 agent-team-audit 改为 audit-engine
使用场景:
不使用场景:
执行前读取 .aria/config.json,缺失则使用默认值。参见 config-loader。
| 字段 | 默认值 | 说明 |
|---|---|---|
audit.enabled | false | 启用 audit-engine 审计 (新) |
audit.checkpoints.pre_merge | "off" | pre_merge 检查点模式 |
experiments.agent_team_audit | false | 旧配置 (向后兼容,自动映射到 audit.*) |
experiments.agent_team_audit_points | ["pre_merge"] | 旧配置 (向后兼容) |
upm.milestone_driven | false | 启用 C.2.6 里程碑子进度追加 (opt-in) |
phase_c_integrator.pre_merge_gate.enabled | true | 启用 C.2.4 pre-merge precondition gate (v1.3.0+) |
phase_c_integrator.submodule_gate.mode | "block" (v1.49.0+ default) / "warn" (legacy) / "off" (bypass) | C.2.4.5 submodule pointer regression gate 模式 (Spec aria-submodule-pointer-regression-gate) |
phase_c_integrator.pre_merge_gate.ci_backends | null (auto-detect) / [] (explicit disable) / [{name: "..."}] (explicit list) | v1.31.0+ CI backend 选择 (替代旧 primitive_preference). 见 §C.2.4.X CI Backends |
phase_c_integrator.pre_merge_gate.no_ci_fallback | "skip_with_warning" | 无可用 CI backend 时降级 (skip_with_warning / abort). v1.31.0+ 替代旧 no_aether_fallback (alias 仍读, 发 deprecation warning, v2.0 移除) |
phase_c_integrator.pre_merge_gate.wait_timeout_seconds | 1800 | wait+retry max 等待时长 (默认 30 min) |
phase_c_integrator.pre_merge_gate.wait_check_intervals | [30,60,120,300,300] | 指数退避秒数; 数组耗尽后重复 intervals[-1] |
phase_c_integrator.pre_merge_gate.primitive_call_timeout_seconds |
当 audit.enabled=true 且 audit.checkpoints.pre_merge != "off" 时,C.2 合并前触发 audit-engine (pre_merge 检查点)。
旧配置 experiments.agent_team_audit=true 且 "pre_merge" in agent_team_audit_points 自动映射到新配置。
| 步骤 | Skill | 职责 | 输出 |
|---|---|---|---|
| C.1 | commit-msg-generator | Git 提交 | commit_sha, message |
| C.2 | branch-manager | PR/合并 | pr_url, pr_number |
context:
phase_cycle: "Phase4-Cycle9"
module: "mobile"
changed_files: ["lib/auth.dart", "test/auth_test.dart"]
branch_name: "feature/mobile/TASK-001-add-auth" # 来自 Phase B
test_results: # 来自 Phase B
passed: true
coverage: 87.5
# v1.1.0 新增: branch-finisher 输出
completion_option: 1 # 来自 branch-finisher
worktree_path: ".git/worktrees/TASK-001-xxx" # 可选
validation_report: # 来自 branch-finisher
passed: true
blocking_failures: 0
warnings: 1
config:
skip_steps: []
params:
enhanced_markers: true # 使用增强提交标记
create_pr: true # 是否创建 PR
C.1 - Git 提交:
skill: commit-msg-generator
params:
enhanced_markers: true
subagent_type: "from_context"
phase_cycle: "from_context"
module: "from_context"
skip_if:
- no_changes_to_commit: true
action:
- 分析暂存区变更
- 生成规范提交消息
- 执行 git commit
output:
commit_sha: "abc1234"
commit_message: "feat(auth): 添加用户认证..."
C.2 - PR/合并:
skill: branch-manager
action: pr
skip_if:
- no_pr_needed: true
- direct_push_allowed: true
pre_hook: # audit-engine 检查点
audit_engine:
checkpoint: pre_merge
步骤:
1. 通过 config-loader 读取 .aria/config.json audit 块
2. 检查 audit.enabled — false 则跳过,保持现有行为不变
3. 检查 audit.checkpoints.pre_merge — "off" 则跳过
4. 如启用: 调用 audit-engine
- checkpoint: "pre_merge"
- mode: 来自配置 (convergence / challenge / adaptive)
- context: PR diff (branch_name vs base)
5. 处理 verdict:
- PASS / PASS_WITH_WARNINGS → 继续推送和创建 PR
- FAIL → 阻塞合并,输出审计报告
backward_compat:
audit.enabled=false: 完全跳过,Phase C 行为与之前完全相同
旧配置 experiments.agent_team_audit: 由 audit-engine 内部映射处理
fallback_description: |
audit-engine 内部通过 agent-team-audit 单轮引擎执行审计。
直接调用 agent-team-audit 已由 audit-engine 编排层取代。
on_fail: 阻塞合并, 输出审计报告
on_skip: 继续合并 (审计未启用)
action:
- (如 audit.enabled) 触发 audit-engine (pre_merge 检查点)
- 推送分支到远程
- 创建 Pull Request
- (可选) 自动合并
output:
pr_url: "https://..."
pr_number: 123
audit_verdict: "PASS" # 如审计启用 (PASS | PASS_WITH_WARNINGS | FAIL)
audit_report: ".aria/audit-reports/pre_merge-{timestamp}.md"
> **注意**: branch-manager 会自动处理 Cloudflare Access 配置。
> 统一规范见 `../forgejo-sync/PRE_CHECK.md`
C.2.4 - Pre-Merge Precondition Gate (v1.3.0+):
触发条件:
- C.2 action PR 已创建 (PR_NUMBER + PR_URL 已知)
- 即将调用 branch-manager merge action (auto_merge=true 或 user-triggered continue)
- 配置 phase_c_integrator.pre_merge_gate.enabled: true (默认)
primitive 调用:
- aether ci status --branch <MAIN_BRANCH> --in-flight --json (查主干是否有 in-flight)
⚠️ <MAIN_BRANCH> 取本项目主干的真实名字 — **本项目是 `master`, 不是 `main`**。
照抄字面 main 正是 aria-plugin #137: 查一个不存在的分支返回「没有在跑的」⇒ 恒放行。
- aether ci status --branch <PR_BRANCH> --json (查本 PR CI 状态)
- aria 端 verdict 计算 (aether-pre-merge-check skill 从未实施, P0-B not shipped)
三态结果:
green: 本 PR CI passing + main 无 in-flight CI → 继续 branch-manager merge
(v1.65.0+ 亦含: path coverage not_applicable + main 无 in-flight, 带警告放行)
wait: main 有 in-flight CI run OR PR CI pending → 进入 wait+retry (workflow-runner wait_recoverable) OR PR CI not_found (远端零 run, v1.66.5+ #152)
fail: PR CI failing OR primitive 错误 → BLOCK + 报告
output:
pre_merge_verdict: "green" | "wait" | "fail"
in_flight_runs: [{run_id, branch, started_at, elapsed_seconds}] # wait 时
pr_ci_status: "passing" | "failing" | "pending" | "not_applicable" | "not_found" # not_applicable = gate 层产生 (v1.65.0+); not_found = backend 层零 run, v1.66.5+
primitive_used: "aether-ci-cli" | "manual"
primitive_version_sha: "f29abee" # aether-cli #116 baseline
path_coverage: {decision, workflows_scanned, matched_workflows, changed_files_count, reason, dispatchable_workflows} # v1.65.0+, 评估执行时在场; dispatchable_workflows v1.66.5+
gate_error: {kind, message, prompt_after_observations?} # v1.66.5+ 三类在场, 见 Output schema
C.2.4.5 - Submodule Pointer Regression Gate (v1.28.0+):
触发条件:
- C.2.4 verdict=green (CI gate 已通过)
- 即将调用 branch-manager merge action
- 配置 phase_c_integrator.submodule_gate.mode: "block" (v1.49.0+ default) | "warn" (legacy opt-out) | "off" (emergency bypass)
primitive 调用:
- git fetch origin (bare, 更新所有 ref) — 强制, 失败 abort
- git -C <submodule> fetch origin — 每 submodule
- git -C <submodule> merge-base --is-ancestor MASTER_PTR FEATURE_PTR — 主 ancestry 检查
- 双向 ancestry 区分 regression (case c) vs divergence (case d)
三态结果:
pass: 所有 submodule pointer 是 forward bump 或 no-change 或 first-time
block: 至少一个 submodule pointer 是 regression 或 divergence (v1.49.0+ default; v1.28.0 was warn-only)
bypass: per-PR commit trailer `Submodule-Rollback: ...` 或 PR label `submodule-rollback-approved` 允许 + audit log
output:
gate_verdict: "pass" | "block" | "warn" | "bypass"
affected_submodules: [{path, master_sha, feature_sha, verdict, override}]
telemetry_written: <metrics file path>
C.2.5 - Multi-Remote Push Enforcement:
触发条件:
- Phase C.2 合并成功 (master 已 fast-forward)
- 配置 phase_c_integrator.multi_remote_push.enabled: true (默认)
skill: git-remote-helper (降级: 内联实现)
action: 见下方 ### C.2.5 详细说明
C.2.6 - UPM Milestone Sub-progress Append (optional):
触发条件:
- C.2.5 multi-remote push 已完成 (或跳过)
- 配置 upm.milestone_driven: true (默认 false,opt-in)
- 当前 commit 与某 User Story 关联 (commit message 含 US-XXX 或 spec change_id)
action: 见下方 ### C.2.6 详细说明
backward_compat: upm.milestone_driven=false 时完全跳过,Phase C 行为与之前完全相同
新增于 v1.3.0 — 修复 Forgejo Issue #60 "phase-c-integrator 缺少 pre-merge safety gate"。 源于 2026-05-02 SilkNode PR-321 cancel PR-322 main CI Run #3161 (459s 部署观测丢失)。 Consume aether
--in-flightprimitive (aether-cli #116, SHAf29abee2026-05-06)。
Naming 命名空间澄清: phase-c-integrator-level 子步骤标签 (C.2.x) 为 orchestrator-tier,与 branch-manager 内部实现层 (也用 C.2.x sequence: C.2.1 sync / C.2.2 push / C.2.3 create-PR / C.2.4 wait-approval / C.2.5 merge) 是独立 label namespace。本 SKILL §C.2.4 = "pre-merge precondition gate" (orchestrator);branch-manager 内部 C.2.4 = "等待审批" (implementation);同名不同 tier,语义独立。
触发条件:
auto_merge=true 自动 / auto_merge=false user-triggered)phase_c_integrator.pre_merge_gate.enabled: true (默认)与 branch-manager 边界 (不重叠):
| Skill | 职责 | 调用顺序 |
|---|---|---|
| branch-manager (C.2.1-C.2.3) | sync rebase + push branch + create PR | gate 之前 |
| phase-c-integrator C.2.4 | pre-merge gate 三态判定 | gate (本段) |
| branch-manager (C.2.4-C.2.5) | wait approval + merge API call | gate green 后 |
📌 改这段代码前先读:
references/pre-merge-gate-empirical-traps.md—— 一页, 11 条实测踩出来的坑 (§一~§五 7 条 + §六 4 条 零 run 折叠, aria-plugin#152; 活体证据行不计) (ls-remote 零命中返 rc=0 · 参数被当 glob ·UnicodeDecodeError不是OSError子类 · 核验插入点 · 测试隔离接缝 …)。每一条都不能靠读代码想出来。
执行流程:
aether --help | grep -q "in-flight" 验证 binary 含 P0-A flag,缺失 → fail-fast 提示 "请升级 aether ≥ commit f29abee (2026-05-06)"resolve_ci_backend(cfg) 按 config 显式 ci_backends 顺序探测,或 fallback 到 BACKENDS list 静态顺序 (Aether-first, GHA-stub-second);所有 backend probe=False → 按 no_ci_fallback 配置降级。详见 §C.2.4.X CI Backends
2.2. 分支存在性核验: main 恒查 (#137); PR 仅 pr_ci_status=not_found 时查 (#152, 第七个早退 pr-branch-not-found → fail): 在上面两道早退与 precheck 之后、path coverage 评估之前, 先确认 main_branch 在目标 remote 上确实存在 (无条件执行)。PR 分支存在性核验则延后 —— 仅当 (a) 腿 pr_ci_status 返回 not_found (远端零 run) 时才补一次 (第七个早退, 见步骤 5)。判据是解析出的 ref 名列表中的精确字符串比对, ⛔ 不看退出码 (零命中亦返 0), ⛔ 不用 glob/pattern (会把 mast* 当成命中 master)。main 不存在 → verdict=fail + gate_error.kind=main-branch-not-found; 核验本身没做成 (远端不可达等) → main-branch-verify-failed; PR 分支 (仅 not_found 后核验) 不存在 → verdict=fail + gate_error.kind=pr-branch-not-found; PR 侧核验本身没做成则不早退, 继续 wait, 但 message 末尾附加核验失败详情。以上均不可混。为什么必须有这一步: backend 结构上无法区分「分支不存在」与「分支没有正在跑的构建」, 两者都返空 runs ⇒ 判 green ⇒ 主干名写错时 Rule #8 这条腿恒真、等于不存在 (本项目主干是 master 而缺省值是 main, #137 即此); PR 侧同理 (#152 F5): 「PR 分支不存在」与「存在但零 run」在 backend 出口逐字节同形2.5. Path coverage 评估 (v1.65.0+, aria-plugin #122; path_coverage_enabled=true 默认): evaluate_path_coverage(main_branch, pr_branch) 解析仓内 workflow (.forgejo/.gitea/.github 三目录) 的 on: push/pull_request 触发 paths, 与 git diff --name-only --no-renames <main>...<pr> 变更集求交, 三值 decision: covered (会/无法排除会触发) / not_applicable (高置信零覆盖) / unknown (评估失败)。fail-toward-covered: 一切不确定 (解析失败 / git 失败 / 未建模构造) → 行为退回现状。执行上下文契约: 在执行 C.2 合并的目标仓根内调用 (子模块合并 → 子模块根); main_branch 显式传真值 (本项目 master), 不依赖 CLI default
3. Query main in-flight: aether ci status --branch <MAIN_BRANCH> --in-flight --json → parse data.runs[] (⚠️ <MAIN_BRANCH> 取本项目主干真实名字 —— 本项目是 master; 照抄字面 main 即 #137: 查不存在的分支返回「没有在跑的」⇒ 恒放行。步骤 2.2 的核验就是为了让这种错当场暴露) — 无条件执行, 不因 not_applicable 免除 ((b) 轴保留; stub backend 的 NotImplementedError 亦经此步照常 propagate)
4. Query PR CI status: aether ci status --branch <PR_BRANCH> --json → parse 最近 run 的 status 字段 → 映射为 passing / failing / pending / not_found (零 run, v1.66.5+ #152)。v1.65.0+: decision=not_applicable 时本步跳过 (零覆盖路径不存在可等的 PR CI), pr_ci_status 置 not_applicable
5. Verdict 计算 (aria 端):
pr_ci_status in [failing, error] → verdict=failpr_ci_status == pending → verdict=wait (PR CI 尚未完成)pr_ci_status == not_found → verdict=wait + gate_error.kind=no-run-for-branch (不论 main in-flight; v1.66.5+)not_found 后核验) → verdict=fail + gate_error.kind=pr-branch-not-foundpr_ci_status == not_applicable AND main_in_flight_runs == [] → verdict=green + raw_message 留痕 (v1.65.0+)pr_ci_status == not_applicable AND main_in_flight_runs != [] → verdict=wait (仅 (b) 轴驱动, v1.65.0+)pr_ci_status == passing AND main_in_flight_runs == [] → verdict=greenpr_ci_status == passing AND main_in_flight_runs != [] → verdict=waitgreen → 调用 branch-manager merge action,进入 C.2.5。v1.65.0+ surface 义务 (二者缺一不可): (a) green 来源为 not_applicable 时, AI 必须在 workflow report 加警告行「C.2.4: 变更路径无 CI workflow 覆盖, PR CI wait 已跳过 (not_applicable), main in-flight 已核」; (b) path_coverage.decision == unknown 时 (gate 行为=现状, 但评估器自身失败), AI 必须 surface「C.2.4 path coverage 评估失败 (reason=git-diff-failed / workflow-parse-failed / internal-error), 已按 covered 现状行为处理」— 评估器静默失效是本机制自己要防的恒红病, 不得吞。v1.65.3+ (#126): internal-error 表示评估器自身异常 (非 git 问题、非 workflow 解析问题), 文案须点明「请报 issue」—— 它与另两个 reason 的排查方向完全不同, 混为一谈会把人引向 git 与 main ref
wait → 输出 wait_recoverable 错误给 workflow-runner,触发 wait+retry 循环 (见 workflow-runner SKILL.md §wait_recoverable)。gate_error.kind == no-run-for-branch 时 AI 必须 surface gate_error.message 原文 (不得只写「CI pending, 等待中」); 处方段 (本文唯一定义处, workflow-runner §wait_recoverable Exit condition 2.5 只引用不复制):
🔴 C.2.4:
<gate_error.message 原文>。已连续<record.no_run_observations>次观测到零 run (~<record.elapsed_seconds>s)。处方 (择一, 由你执行; AI 不自动执行): (a) dispatch 命令行 — 已由 gate 渲染进gate_error.message(trigger-matched 档, 受DISPATCH_VIABLE常量与dispatchable_workflows非空控制), AI 只填<owner>/<repo>; message 无此行则 (a) 不出现。⚠️ 活体实测一次 dispatch 产生成对 run 且started_at相同 (见 references/pre-merge-gate-empirical-traps.md §六), gate 取最近 run 时 tie 可能读到 failure — 人核按 run id / 状态综合看 (b) 推一个碰 CI 触发路径的实质 commit 到<pr_branch>(workflow-trigger-matched: matched workflow 声明的 paths;workflow-files-changed: 被改 workflow 自己声明的 paths) — 第二次 push 是普通 diff, paths 正常评; 若 workflow 有branches过滤且不含本分支, 推 commit 无效 → 改分支名或走 (a)/(c) (path_coverage 不建模 branches, 人核) [unknown/empty-diff/ pc=None 档不出现本行] (c) 继续等待 (continue) / 放弃 (abort)
prompt 由 workflow-runner §wait_recoverable Exit condition 2.5 按观测计数触发; 交互式直调 §C.2.4 (无 workflow-runner) 时无计数, 读者自行按 message 与上方处方处置。
Subprocess 调用规范:
subprocess.run(..., timeout=primitive_call_timeout_seconds) 强制 (默认 30s)fail verdict0 = success / 1-126 = aether 错误 → fail / 127 = binary not found → no_ci_fallback / -SIGTERM = subprocess timeout → retry → 仍失败则 fail。NIE-propagation 例外 (v1.31.0+, Hard Constraint #7): stub backend (e.g. GHA v1.31.0) query 方法 raise NotImplementedError → gate abort (raise to caller),不走 no_ci_fallbackHelper 实现: ${ARIA_PLUGIN_ROOT:-aria}/skills/phase-c-integrator/scripts/pre_merge_gate.py (stdlib + subprocess only)
Output schema:
{
"verdict": "green" | "wait" | "fail",
"pr_ci_status": "passing" | "failing" | "pending" | "not_applicable" | "not_found",
"in_flight_runs": [
{"run_id": 3161, "branch": "main", "started_at": "2026-05-09T12:45:00Z", "elapsed_seconds": 459}
],
"primitive_used": "aether-ci-cli",
"primitive_version_sha": "f29abee",
"raw_message": "...",
"path_coverage": {"decision": "covered|not_applicable|unknown", "workflows_scanned": 1, "matched_workflows": [], "changed_files_count": 2, "reason": "no-triggering-paths", "dispatchable_workflows": []},
"gate_error": {"kind": "main-branch-not-found|main-branch-verify-failed|pr-branch-not-found|no-run-for-branch", "message": "...", "prompt_after_observations": 3}
}
枚举归层注记 (v1.65.0+): not_applicable 由 gate 层产生 (path coverage 短路, 从不来自 backend); backend CIStatus.state Literal 另含 not_found (backend 层值, 远端零 run; v1.66.5+ 起 gate 输出会产生, 见下方 gate_error.kind 消歧表, 列此消除文档与 ci_backends/base.py:29 的历史漂移)。path_coverage 为 additive 可选键 — 仅评估已执行且流程走到最终 verdict 路径时在场; 各早退分支 (no-backend / precheck 失败 / backend query 失败 / enabled:false) 保持六键不变。
gate_error 为 additive 可选键 (aria-plugin #137 / #152) — 三类在场: (i) main 分支存在性核验判 fail (main-branch-not-found / main-branch-verify-failed, verdict=fail, 无 path_coverage); (ii) PR 分支存在性核验判 fail (pr-branch-not-found, verdict=fail, path_coverage 在场 ⇔ path_coverage_enabled); (iii) pr_ci_status=not_found 的 wait 态 (no-run-for-branch, verdict=wait, 同上, 带 prompt_after_observations —— 仅此类带该字段)。kind 是封闭集 4 项, 四个都是副本通道: 同一段文字必定同时写进 raw_message (主通道), 只读 raw_message 的消费方不丢信息。⚠️ 这些早退分支都不保持六键不变 (多一个 gate_error)。
kind 二维消歧表 (分支存在性 × run 存在性; not_found 为 backend 态·主语是 run, *-branch-not-found 为 kind·主语是分支, 二者同词根异义):
| run 存在 (有 run) | run 不存在 (零 run, 含存在性未知/核验失败) | |
|---|---|---|
| 分支存在 | (无 gate_error, 正常 passing/pending/failing 路径) | no-run-for-branch (verdict=wait; 存在性未知/核验失败归此象限, message 末尾带附注后缀) |
| 分支不存在 | — (结构不可达) | main-branch-not-found / pr-branch-not-found (verdict=fail) |
配置参数:
| 参数 | 默认 | 说明 |
|---|---|---|
enabled | true | gate 总开关 (false → 完全跳过 C.2.4,向后兼容) |
ci_backends | null (auto-detect) / [] (disable) / [{name: "..."}] | v1.31.0+ backend 选择. Alias: 旧 primitive_preference 仍读 + deprecation warning |
no_ci_fallback | "skip_with_warning" | 无可用 backend 时 (skip_with_warning / abort). Alias: 旧 no_aether_fallback 仍读 + deprecation warning |
wait_timeout_seconds | 1800 | wait+retry max (默认 30 min) |
wait_check_intervals | [30,60,120,300,300] | 指数退避 (秒); 数组耗尽后重复 intervals[-1] |
primitive_call_timeout_seconds | 30 | 单次 subprocess 调用 timeout |
poll_chunk_seconds | 5 | Ctrl-C polling chunk |
path_coverage_enabled | true | v1.65.0+ 路径覆盖感知开关 (#122, owner sign-off 2026-07-27 单独批默认 true)。false → 不评估, 输出无 path_coverage 键, 行为=v1.64.x |
no_run_prompt_after_observations | 3 | v1.66.5+ (#152) 远端零 run (pr_ci_status=not_found) 连续观测达此次数才 prompt; int ≥2, 不提供 1; 非法值 warn + 回落 3 |
降级行为:
enabled: false → 完全跳过 C.2.4 (与 v1.2.0 行为 100% 一致)no_ci_fallback: skip_with_warning → 跳过 + workflow report 警告no_ci_fallback: abort → BLOCK + 提示安装支持的 CI backendci_backends: []) → 视为"无可用 backend" 路径,按 no_ci_fallback 降级 (canonical way to disable v1.31.0+)gh 装但 GHA stub query 未实现) → 不走 fallback,直接 abort (Hard Constraint #7)--in-flight flag) → fail-fast,不继续执行 (避免 silent skip)[abc]/! 等, 判匹配) / 未建模触发键 (pull_request_target 等, 判 covered; 零贡献仅精确白名单 {workflow_dispatch, schedule}) / paths-ignore 在场 — 一律落 covered/unknown, gate 行为与 v1.64.x 逐字段一致; not_applicable 只在全部 workflow 解析成功且确定不触发时产生。判定规则 1-8 全分割 + reason 封闭集详见 Spec openspec/changes/phase-c-gate-path-coverage-not-applicable/proposal.md §1Race condition 处理: gate 检查与 merge call 之间,main 可能新触发 CI run。窗口最小化 (gate green 后立即调 merge),不消除 race。深度 mitigation 留 future Spec。
新增于 v1.31.0 — 实施 Spec
aria-ci-backend-abstraction(Approved 2026-05-28, post_spec R2 CONVERGED unanimous PASS_WITH_WARNINGS × 3)。源于 2026-05-27 boundary audit P0 C5+C6 — pre_merge_gate.py 去 Aether-only 假设。
Backend 抽象: pre_merge_gate.py 通过 aria/skills/phase-c-integrator/scripts/ci_backends/ 包提供的 CIBackend ABC + CIStatus / InFlightStatus dataclass 调用 CI primitive。每个 backend 实现两个 abstract method (query_pr_ci / query_branch_in_flight) + 一个 ClassVar (name) + classmethod probe()。
Supported backends (v1.31.0):
| Backend | name | Status | Real implementation? |
|---|---|---|---|
| Aether | aether-ci-cli | ✅ Default, full | Yes (10CG Lab internal, migrated from v1.30.0 pre_merge_gate.py) |
| GitHub Actions | github-actions | 🚧 Stub | No — probe() real (gh CLI + auth check), query_*() raise NotImplementedError. Real implementation deferred to v1.32.0+ next cycle |
Backend selection algorithm (resolve_ci_backend(config)):
if config["ci_backends"] is [] (empty list):
return None # explicit disable per AC-4.5
elif config["ci_backends"] is non-empty list:
try each entry in user-specified order, return first probe()=True
elif config["ci_backends"] is None or missing:
iterate BACKENDS list (Aether → GHA), return first probe()=True
BACKENDS list order (ci_backends/__init__.py static import, Hard Constraint #8):
BACKENDS: list[type[CIBackend]] = [AetherBackend, GitHubActionsBackend]
→ Aether-first precedence locked. 不允许 decorator-based registration / setuptools.entry_points / 任何 dynamic discovery。
Config schema example:
{
"phase_c_integrator": {
"pre_merge_gate": {
"enabled": true,
"ci_backends": null, // auto-detect (default)
// OR: "ci_backends": [], // explicit disable
// OR: "ci_backends": [{"name": "aether-ci-cli"}], // explicit list
"no_ci_fallback": "skip_with_warning", // when no backend available
// Legacy alias (auto-translated + DeprecationWarning, removed in v2.0):
// "primitive_preference": ["aether-ci-cli"],
// "no_aether_fallback": "skip_with_warning"
}
}
}
Hard Constraint #7 (NIE-propagation safety):
Stub backend (e.g. GitHubActionsBackend in v1.31.0) probe() returns True 但 query_*() raise NotImplementedError。gate_check() 必须 propagate NIE to caller,不允许 catch-and-route-to-no_ci_fallback。理由:防止"装了 gh 但实际用 Aether 的项目"因 GHA stub 抢先注册而 Rule #8 静默降级。如需禁用 backend probing,显式设 ci_backends: []。
Probe cache (Hard Constraint #11, Option B):
ci_backends/__init__.py exports cached_probe(backend_cls) + reset_probe_cache()。模块-level dict (_probe_cache) 缓存 probe 结果。禁止 @functools.lru_cache (test isolation hazard)。测试 setUp/tearDown 必须调 reset_probe_cache() 防止状态泄漏。
Adding a new backend (e.g. GitLab CI):
ci_backends/gitlab_ci.py 继承 CIBackend,实现 name / probe / query_pr_ci / query_branch_in_flight (optionally precheck)ci_backends/__init__.py 加 import + 加到 BACKENDS list (位置决定 precedence)tests/test_ci_backends.pyNIE 是 stub 临时状态: 如果新 backend 计划只做 stub,所有 query_*() 必须 raise NotImplementedError 带 operable message (含 "PR welcome" 提示 + 显式 disable instructions per ci_backends: [])。Hard Constraint #4 + AC-2.5 enforced via test。
新增于 v1.28.0 — 实施 Spec
aria-submodule-pointer-regression-gate(Approved 2026-05-24, DEC-20260524-002)。 源于 2026-05-23 PR #123 silent submodule pointer regression incident (6fea5d7静默回滚 4 commits, 被 post-merge audit catch + fast-forward fixa8e0096)。 Closes Forgejo Aria #124。
Two-phase rollout (✅ flipped to block default in v1.49.0, 2026-06-21):
mode=warn 默认 — 检测 + 日志 WOULD-BLOCK, 不阻止 mergemode=block 默认 — 检测到 regression/divergence + 无 override → 拒绝 merge.aria/decisions/2026-06-21-v1.49.0-block-flip.md (主仓)。触发条件:
phase_c_integrator.submodule_gate.mode: "block" (v1.49.0+ default) | "warn" (legacy opt-out) | "off" (skip 完全)执行流程 (Bash gate, 见 scripts/submodule_gate.sh):
# Step 1: fail-loud fetch with bounded retries (1s/2s/4s × 3 attempts)
# Drop fragile `grep success patterns` — use exit code only (AD-FOLLOWUP-1)
BEFORE_REMOTE=$(git rev-parse origin/master 2>/dev/null || echo "FIRST_RUN")
for delay in 1 2 4; do
if git fetch origin 2>&1; then FETCH_OK=1; break; fi
sleep "$delay"
done
[[ "${FETCH_OK:-0}" != 1 ]] && {
log_telemetry "FETCH_FAILURE" "$BEFORE_REMOTE" "(unknown)" "fetch_exhausted_retries"
echo "BLOCK: git fetch origin failed after 3 attempts" >&2
exit 1
}
# Step 2: refspec assertion (skip on FIRST_RUN)
AFTER_REMOTE=$(git rev-parse origin/master)
if [[ "$BEFORE_REMOTE" != "FIRST_RUN" && "$BEFORE_REMOTE" != "$AFTER_REMOTE" ]]; then
if ! git merge-base --is-ancestor "$BEFORE_REMOTE" "$AFTER_REMOTE" 2>/dev/null; then
echo "BLOCK: origin/master rewritten (non-ancestor advance) — operator confirm required" >&2
exit 1
fi
fi
# Step 3: per-submodule loop
exit_code=0
while IFS= read -r SUB; do
[[ -z "$SUB" ]] && continue
git -C "$SUB" fetch origin 2>&1 >/dev/null || true
FEATURE_PTR=$(git ls-tree HEAD "$SUB" | awk '{print $3}')
MASTER_PTR=$(git ls-tree origin/master "$SUB" | awk '{print $3}')
# nil-SHA: first-time submodule (master had no gitlink)
[[ -z "$MASTER_PTR" ]] && {
echo "INFO: $SUB first introduced this PR (no prior master gitlink); gate PASS"
continue
}
# No-change
[[ "$FEATURE_PTR" == "$MASTER_PTR" ]] && {
echo "OK: $SUB unchanged"
continue
}
echo "GATE: submodule=$SUB master=$MASTER_PTR feature=$FEATURE_PTR"
# Forward bump?
if git -C "$SUB" merge-base --is-ancestor "$MASTER_PTR" "$FEATURE_PTR" 2>/dev/null; then
echo "PASS: $SUB forward bump"
continue
fi
# Distinguish regression vs divergent
if git -C "$SUB" merge-base --is-ancestor "$FEATURE_PTR" "$MASTER_PTR" 2>/dev/null; then
VERDICT="REGRESSION"
else
VERDICT="DIVERGENT"
fi
# Check override (commit trailer OR PR label)
if check_override "$SUB" "$MASTER_PTR" "$FEATURE_PTR"; then
echo "ALLOW: $SUB $VERDICT overridden (audit logged)"
log_override "$SUB" "$VERDICT" "$MASTER_PTR" "$FEATURE_PTR"
continue
fi
# Mode dispatch
MODE="${ARIA_SUBMODULE_GATE_MODE:-block}"
if [[ "$MODE" == "warn" ]]; then
echo "WOULD-BLOCK: submodule=$SUB master=$MASTER_PTR feature=$FEATURE_PTR reason=$VERDICT"
log_warn "$SUB" "$VERDICT" "$MASTER_PTR" "$FEATURE_PTR"
else
echo "BLOCK: $VERDICT — submodule=$SUB master=$MASTER_PTR feature=$FEATURE_PTR" >&2
echo " Override 1: commit trailer 'Submodule-Rollback: $SUB $MASTER_PTR->$FEATURE_PTR reason=<reason>'" >&2
echo " Override 2: PR label 'submodule-rollback-approved'" >&2
log_block "$SUB" "$VERDICT" "$MASTER_PTR" "$FEATURE_PTR"
exit_code=1
fi
done < <(git config --file .gitmodules --get-regexp '^submodule\..*\.path$' 2>/dev/null | awk '{print $2}')
exit $exit_code
Override mechanism (per-PR explicit, NOT sticky config):
Commit trailer in merge commit message (accepts both Unicode → and ASCII ->):
Submodule-Rollback: aria a8e0096→3b688a9 reason=v1.24.1 introduced critical regression
Submodule-Rollback: aria a8e0096->3b688a9 reason=同 (ASCII alternative for LANG=C/POSIX safety)
Parser resolves short SHAs (≥7 chars) via git rev-parse before comparison to FEATURE/MASTER pointers. Mismatched SHAs in trailer → reject override.
PR label submodule-rollback-approved (settable only by repo maintainers via Forgejo):
forgejo GET /repos/<owner>/<repo>/issues/<PR>/labelsOverride audit log to metrics/submodule-gate-overrides.jsonl (JSONL append-only, race-safe):
{"timestamp":"...","pr_id":N,"submodule":"...","master_sha":"...","feature_sha":"...","verdict":"REGRESSION","reason":"...","override_type":"trailer"|"label"}
Verdict 三态 (output):
pass — all submodules: forward / no-change / first-timewarn (legacy opt-out) — WOULD-BLOCK logged, merge proceedsblock (v1.49.0+ default) — merge refused, exit 1bypass — override applied, audit logged, merge proceedsOutput schema (JSON):
{
"verdict": "pass" | "warn" | "block" | "bypass",
"affected_submodules": [
{
"path": "aria",
"master_sha": "a8e0096",
"feature_sha": "3b688a9",
"verdict": "REGRESSION",
"override": "trailer" | "label" | null
}
],
"telemetry_files": {
"warns": "metrics/submodule-gate-warns.jsonl",
"overrides": "metrics/submodule-gate-overrides.jsonl",
"blocks": "metrics/submodule-gate-blocks.jsonl",
"misses": "metrics/submodule-gate-misses.jsonl"
}
}
配置参数:
| 参数 | 默认 | 说明 |
|---|---|---|
mode | "block" (v1.49.0+ default) / "warn" (legacy) / "off" | "warn" 仅日志 / "block" 拒绝 merge / "off" 跳过 gate |
fetch_retries | [1, 2, 4] | 指数退避秒数 |
metrics_dir | "metrics/" (relative to aria-plugin root, NOT main repo) | 4 JSONL append-only 文件位置 |
forgejo_api_timeout_s | 5 | PR label fetch timeout |
nil_sha_action | "pass_with_info" | first-time submodule (master 无 gitlink) → PASS + INFO log |
降级行为:
mode: off → 完全跳过 §C.2.4.5 (与 v1.27.x 行为 100% 一致, 用于紧急 bypass 全 cycle)git fetch origin 3-attempt failure → terminal block (per wait_recoverable pattern, owner remediation: 检查 auth/network/URL drift)git ls-tree empty output (nil-SHA case) → PASS + INFO (first-time submodule case)git merge-base --is-ancestor exit 128 (SHA not in submodule DB after fetch) → BLOCK + "submodule fetch incomplete, retry" hintPerformance budget:
Race condition 处理 (per backend-architect R3 missing scenario):
origin/master during gate execution: refspec assertion (Step 2) compares BEFORE/AFTER rev-parseTripwire (mechanical detection of (B+) gate misses):
.forgejo/workflows/submodule-gate-tripwire.yml in 10CG/Aria main repo (NOT aria/cron/ in aria-plugin)metrics/submodule-gate-misses.jsonl + file Forgejo issue with label gate-tripwire-counton: workflow_dispatch only; tripwire periodic execution migrated to host-cron (0 4 * * 0, v1.41.0 R-fix-2 — Actions runner 无 forgejo 凭据 + CF Access 墙; standalone scripts/submodule-tripwire-audit.sh). v1.49.0 block-flip 依赖 host-cron tripwire (4 clean runs) 作独立兜底, 非 workflow cronHelper 实现: ${ARIA_PLUGIN_ROOT:-aria}/skills/phase-c-integrator/scripts/submodule_gate.sh (Bash, stdlib + git only)
Cross-references:
openspec/changes/aria-submodule-pointer-regression-gate/proposal.md.aria/decisions/2026-05-24-aria-124-submodule-pointer-regression-gate.mdstandards/conventions/submodule-pointer-hygiene.md (zero-code companion, NOT numbered Rule)6fea5d7 + fast-forward fix a8e0096触发条件:
phase_c_integrator.multi_remote_push.enabled: true (默认)与 branch-manager 边界 (不重叠):
| Skill | 职责 | Remote 范围 |
|---|---|---|
| branch-manager (C.2 PR 发起前) | 推送 feature 分支 + 创建 PR | 仅 origin |
| phase-c-integrator C.2.5 (PR 合并后) | 推送 master + 多 remote SHA 验证 | 所有 enforced remote |
执行流程:
expected_sha = git rev-parse HEAD (合并后本地 master HEAD)git submodule status --recursiveENFORCED_REMOTES: skill 级 enforced_remotes == null 时继承顶层 multi_remote.enforced_remotes, 空则自动发现所有 remotegit-remote-helper.push_all_remotes(SUBMODULE.path, SUBMODULE.branch, [REMOTE])git -C <path> push <remote> <branch>)失败优先级 (决策表):
| 条件 | 行为 |
|---|---|
remote ∈ read_only_remotes | warning 降级, 继续 (最高优先级) |
fail_on_partial_push: false + 非 read_only | warning, 继续 |
fail_on_partial_push: true + 非 read_only (默认) | 阻断, 输出修复命令 |
Per-Remote Matrix 示例:
origin: sub1 ✅ sub2 ✅ main ✅ (已推)
github: sub1 ✅ sub2 ❌ (network timeout) → 跳过 main github; 但 origin 已完成
子模块 detached HEAD: 沿用 helper canonical (detached_head: true + HEAD SHA 比较), 警告但不阻断。
降级策略: 检测 test -f "${ARIA_PLUGIN_ROOT:-aria}/skills/git-remote-helper/SKILL.md" 存在性 (路径相对项目根; ARIA_PLUGIN_ROOT 环境变量优先)。不可用时用内联降级 (不重试, 简化实现), schema 仍一致。
Race condition 处理: verify 4 次 attempt 全部 match=false 默认阻断, 记录 "possible race condition"。
新增于 v1.16.0 — 修复 Forgejo #22 "multi-PR cycle UPM 信息盲区"问题。 源于 M1 closeout (2026-04-23) single-D.1 一次性更新 85 tasks 的实际痛点
- silknode US-074 multi-PR migration 场景。
触发条件:
upm.milestone_driven: trueUS-XXX 模式关联识别逻辑:
# 1. 从 commit message 中提取 US 编号
# 示例: "feat(m1): T4 complete — DEMO-001 E2E SUCCESS" 含 US-021 前缀
US_REF=$(git log -1 --format="%s %b" | grep -oE 'US-[0-9]+' | head -1)
# 2. 如果 commit message 无 US-XXX,尝试从 spec change_id 推断
if [ -z "$US_REF" ] && [ -n "$SPEC_CHANGE_ID" ]; then
US_REF=$(grep -r "$SPEC_CHANGE_ID" openspec/changes/ \
--include="proposal.md" -l | \
xargs grep -oE 'US-[0-9]+' | head -1)
fi
执行动作:
# 获取当前 commit 信息
COMMIT_SHA=$(git rev-parse --short HEAD)
COMMIT_DATE=$(date +%Y-%m-%d)
COMMIT_TITLE=$(git log -1 --format="%s")
PR_URL="${PR_URL:-}" # 来自 C.2 输出,无则留空
# 构造 sub-bullet
if [ -n "$PR_URL" ]; then
SUB_BULLET=" - ${COMMIT_DATE}: ${COMMIT_SHA} — ${COMMIT_TITLE} (${PR_URL})"
else
SUB_BULLET=" - ${COMMIT_DATE}: ${COMMIT_SHA} — ${COMMIT_TITLE}"
fi
# 定位 UPM 文档中对应 US 行并追加 sub-bullet
UPM_FILE=$(find . -name "unified-progress-management.md" \
-not -path "*/archive/*" | head -1)
if [ -n "$UPM_FILE" ] && [ -n "$US_REF" ]; then
# 将 [ ] IN_PROGRESS 更新为 [~] IN_PROGRESS (如当前状态为 [ ])
sed -i "s/\[ \] \(.*${US_REF}.*\)/[~] \1/" "$UPM_FILE"
# 在 US 行下方追加 sub-bullet
sed -i "/.*${US_REF}.*/a\\${SUB_BULLET}" "$UPM_FILE"
fi
状态标记约定:
| 标记 | 含义 | 触发时机 |
|---|---|---|
[ ] | 未开始 / IN_PROGRESS (原有) | 初始状态 |
[~] | 进行中,有中间进度记录 | C.2.6 首次追加时自动升级 |
[x] | COMPLETED | D.1 final pass 写入 |
sub-bullet 格式示例:
- [~] US-021: M1 MVP Layer 2 实现
- 2026-04-20: abc1234 — feat(m1): T1 infra complete (https://forgejo.../pulls/18)
- 2026-04-22: def5678 — feat(m1): T3 orchestrator ready (https://forgejo.../pulls/19)
- 2026-04-23: ghi9012 — test(m1): T5 DEMO E2E complete (https://forgejo.../pulls/20)
DoD:
upm.milestone_driven=true 时: UPM 文档对应 Story 行下出现 sub-bullet,状态从 [ ] 升级为 [~]upm.milestone_driven=false (默认) 时: Skill 无行为变化,完全向后兼容配置示例 (.aria/config.json):
upm:
milestone_driven: false # 默认 false,保留 D.1-only 现有行为
# 设为 true 启用 C.2.6 中间进度追加
success: true
steps_executed: [C.1, C.2]
steps_skipped: []
results:
C.1:
commit_sha: "abc1234"
commit_message: "feat(auth): 添加用户认证..."
C.2:
pr_url: "https://..."
pr_number: 123
context_for_next:
commit_sha: "abc1234"
pr_url: "https://..."
当本 cycle 走 emergency_hotfix lane (state-scanner emergency_hotfix 规则触发, hotfix/* 分支) 时, C.2 的 pre_merge audit 调用点 仅 audit.enabled=true 且 audit.checkpoints.pre_merge != "off" 时, 把 audit mode 降级到 convergence (不 challenge) —— prod 紧急修复不必跑 15-30min challenge ceremony。
C.2 合并前若会话已很长 (多 cycle 累积), 用 aria-context-monitor 判断"本 cycle 收尾后是否该暂停换会话", 避免 pre-merge gate 等待期硬撞 context 上限丢上下文:
python3 "${CLAUDE_PLUGIN_ROOT:-aria}/skills/aria-token-telemetry/scripts/token_telemetry.py" --project-root .
used_percentage (relay 路径) >85% → 建议 merge 完成后即暂停 + 写 handoff。advisory, 不自动中断。详见 phase-b-developer 同名章节。
会话收尾触发 (session-closer TASK-007): merge 完成后调 closeout_trigger —— 占用 ≥ 阈值 + 有未交接成果时 advise /session-closer(advisory, 不自动执行)。契约 (I-1): 喂 token_telemetry.py 的输出 (含 source), 非 relay cache 原始文件 (先 token_telemetry.py > $TEL 再 closeout_trigger.py --telemetry-json $TEL, 详见 phase-b-developer 同名章节)。
| 条件 | 跳过步骤 | 检测方法 |
|---|---|---|
| 无变更 | C.1 | git status --porcelain 为空 |
| 不需要 PR | C.2 | 配置或分支策略 |
| 直接推送 | C.2 | 在 develop 分支 |
skip_evaluation:
C.1:
- check: git status --porcelain
skip_if: empty
reason: "没有需要提交的变更"
C.2:
- check: branch_name
skip_if: in [develop, main]
reason: "主分支不需要 PR"
- check: config.create_pr
skip_if: false
reason: "配置为不创建 PR"
╔══════════════════════════════════════════════════════════════╗
║ PHASE C - INTEGRATION ║
╚══════════════════════════════════════════════════════════════╝
📋 执行计划
───────────────────────────────────────────────────────────────
C.1 commit-msg-generator → Git 提交
C.2 branch-manager → 创建 PR
🚀 执行中...
───────────────────────────────────────────────────────────────
✅ C.1 完成 → Commit: abc1234
Message: feat(auth): 添加用户认证 / Add user authentication
✅ C.2 完成 → PR #123 已创建
URL: https://github.com/...
📤 上下文输出
───────────────────────────────────────────────────────────────
commit: abc1234
pr: #123
ready_for: Phase D (可选)
输入:
context:
branch_name: "feature/add-auth"
test_results: { passed: true }
执行:
C.1: 提交代码 → abc1234
C.2: 创建 PR → #123
输出:
commit_sha: "abc1234"
pr_url: "https://..."
输入:
config:
create_pr: false
执行:
C.1: 提交代码
C.2: 跳过 (不需要 PR)
输出:
steps_skipped: [C.2]
commit_sha: "abc1234"
输入:
context:
branch_name: "develop" # 在主分支
执行:
C.1: 提交代码
C.2: 跳过 (主分支不需要 PR)
额外: git push
输出:
commit_sha: "abc1234"
pushed: true
feat(auth): 添加用户认证 / Add user authentication
- 实现 JWT token 验证
- 添加登录 API 端点
🤖 Executed-By: mobile-developer subagent
📋 Context: Phase4-Cycle9 功能开发
🔗 Module: mobile
| 标记 | 来源 |
|---|---|
| 🤖 Executed-By | 执行的 Agent 类型 |
| 📋 Context | Phase/Cycle + 任务描述 |
| 🔗 Module | 活跃模块名 |
| 错误 | 原因 | 处理 |
|---|---|---|
| 提交失败 | hook 拒绝 | 显示 hook 错误,提示修复 |
| PR 创建失败 | 权限问题 | 提示检查权限 |
| 推送失败 | 远程冲突 | 提示拉取最新代码 |
on_commit_hook_failure:
action: stop
report:
- Hook 错误信息
- 缺少的标记或格式问题
next_step: "使用 commit-msg-generator 重新生成消息"
新增于 v1.1.0 - 集成 branch-finisher 完成流程
completion_option_handling:
"[1] 提交并创建 PR":
action: 执行完整 Phase C
steps: [C.1, C.2]
worktree_cleanup: 在 PR 创建后询问
"[2] 继续修改":
action: 跳过 Phase C
steps: []
reason: "用户选择继续修改,不进入集成阶段"
"[3] 放弃变更":
action: 跳过 Phase C
steps: []
reason: "变更已放弃,无需集成"
worktree_cleanup: 强制执行
"[4] 暂停保存":
action: 跳过 Phase C
steps: []
reason: "用户选择暂停,稍后恢复"
pre_check:
# 检查 branch-finisher 输出
completion_option:
required: true
valid_for_phase_c: [1] # 只有选项 1 进入 Phase C
# 检查测试验证结果
validation_report:
required: true
must_pass: true
warn_on: warnings > 0
# 检查 Worktree 状态
worktree_path:
check: if exists
action: 记录,用于后续清理
enhanced_flow:
1. 接收 branch-finisher 输出
├── completion_option
├── validation_report
└── worktree_path (可选)
2. 前置检查
├── 验证 completion_option == 1
├── 验证 validation_report.passed
└── 记录 worktree_path
3. 执行 C.1 (提交)
├── 使用 commit-msg-generator
├── 包含增强标记
└── 关联 task_id
4. 执行 C.2 (PR)
├── 使用 branch-manager
├── 创建 PR
└── 包含测试验证结果
5. Worktree 清理决策
├── PR 创建成功?
├── 询问用户是否清理
└── 执行清理或保留
worktree_cleanup_timing:
trigger: PR 创建成功后
default: 询问用户
options:
- "[1] 立即清理 (推荐)"
- "[2] 保留 worktree"
auto_cleanup_if:
- PR merged
- PR closed
context_for_next:
# 原有字段
commit_sha: "abc1234"
pr_url: "https://..."
pr_number: 123
# v1.1.0 新增字段
completion_option: 1
worktree_status: "cleaned" | "preserved"
validation_summary:
passed: true
warnings: 1
phase-b-developer
│
│ context:
│ - branch_name
│ - test_results
▼
branch-finisher (v1.1.0 新增)
│
│ context:
│ - completion_option
│ - validation_report
│ - worktree_path
▼
phase-c-integrator (本 Skill)
│
│ context_for_next:
│ - commit_sha
│ - pr_url
│ - worktree_status
▼
phase-d-closer
最后更新: 2026-03-27 Skill版本: 1.2.0
30 |
| 单次 aether subprocess 调用 timeout |
phase_c_integrator.pre_merge_gate.poll_chunk_seconds | 5 | Ctrl-C polling chunk 大小 |
phase_c_integrator.pre_merge_gate.path_coverage_enabled | true | v1.65.0+ 路径覆盖感知 (aria-plugin #122): 变更路径结构性无 CI workflow 覆盖时产 not_applicable, 跳过 (a) PR CI wait ((b) main in-flight 照查)。见 §C.2.4 步骤 2.5 |
phase_c_integrator.pre_merge_gate.no_run_prompt_after_observations | 3 | v1.66.5+ (#152) 远端零 run (pr_ci_status=not_found) 连续观测达此次数才 prompt; int ≥2, 不提供 1; 非法值 warn + 回落 3 |
fail → BLOCK + 输出 verdict + raw_message,phase-c-integrator return failure