prune

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Prune Workflows Skill

工作流清理Skill

VCS Provider

VCS 提供商

This skill's safeguards use VCS operations internally (open PR detection). The orchestrate handler manages VCS provider dispatch automatically. No
gh
/
glab
/
az
commands needed — the MCP server handles provider dispatch.
该Skill的保护机制内部使用VCS操作(检测开放PR)。编排处理程序会自动管理VCS提供商的调度。无需使用
gh
/
glab
/
az
命令——MCP服务器会处理提供商调度。

Overview

概述

Bulk-cancel stale non-terminal workflows that have accumulated in the pipeline. Wraps the
prune_stale_workflows
orchestrate action with an interactive dry-run-then-confirm UX so the user always sees the candidate set before any state mutates.
Pruning is a maintenance operation -- not a workflow phase. It produces
workflow.pruned
events alongside the standard
workflow.cancelled
events emitted by the underlying cancel path, so downstream views can distinguish user-intent cancellations from batch cleanup.
批量取消流水线中累积的已过时非终端工作流。该Skill为
prune_stale_workflows
编排操作封装了“干运行预览+确认”的交互式流程,确保用户在任何状态变更前都能查看待清理的候选工作流集合。
清理是一项维护操作——而非工作流阶段。除了底层取消流程生成的标准
workflow.cancelled
事件外,还会生成
workflow.pruned
事件,以便下游视图区分用户主动发起的取消操作与批量清理操作。

Triggers

触发条件

Activate this skill when:
  • User runs
    prune
    command
  • User says "prune workflows", "clean stale workflows", "pipeline cleanup"
  • exarchos:exarchos_view({ action: "pipeline", scope: "all" })
    shows many inactive workflows the user wants to clear in bulk. Prune observes candidates with
    scope: "all"
    because the default view is repo-scoped and hides the legacy rows (workflows started before repo identity was recorded) that prune exists to drain — a repo-scoped observation would miss the very inventory it targets.
在以下场景激活该Skill:
  • 用户运行
    prune
    命令
  • 用户说出“prune workflows”“clean stale workflows”“pipeline cleanup”
  • exarchos:exarchos_view({ action: "pipeline", scope: "all" })
    显示大量用户希望批量清理的非活跃工作流。清理操作会检测
    scope: "all"
    的候选工作流,因为默认视图是仓库范围的,会隐藏清理操作旨在处理的“遗留”工作流(仓库身份记录前启动的工作流)——若仅检测仓库范围的工作流,会错过目标清理对象。

Prerequisites

前置条件

  • An exarchos state directory with one or more non-terminal workflows
  • For safeguard checks against live PRs:
    gh
    available in PATH (the orchestrate handler shells out)
  • For safeguard checks against branch activity:
    git
    available in PATH
  • 存在包含一个或多个非终端工作流的exarchos状态目录
  • 若要针对活跃PR执行保护检查:PATH中需包含
    gh
    (编排处理程序会调用shell命令)
  • 若要针对分支活动执行保护检查:PATH中需包含
    git

Process

流程

Step 1: Dry-Run Preview

步骤1:干运行预览

Always start with
dryRun: true
. This call performs candidate selection and safeguard evaluation but does not mutate any workflow state.
typescript
exarchos:exarchos_orchestrate({
  action: "prune_stale_workflows",
  args: {
    dryRun: true
  }
})
The response shape is:
ts
{
  candidates: [
    { featureId: string, phase: string, workflowType: string, stalenessMinutes: number }
  ],
  skipped: [
    { featureId: string, reason: "open-pr" | "active-branch" }
  ]
}
Optional args:
  • thresholdMinutes
    -- staleness cutoff. Default is 10080 (7 days).
  • includeOneShot
    -- whether to include
    oneshot
    workflows in the candidate set. Default
    true
    .
  • force
    -- not relevant in dry-run; only honored in apply mode (Step 4).
始终以
dryRun: true
启动。该调用会执行候选工作流选择和保护机制评估,但不会变更任何工作流状态。
typescript
exarchos:exarchos_orchestrate({
  action: "prune_stale_workflows",
  args: {
    dryRun: true
  }
})
响应格式如下:
ts
{
  candidates: [
    { featureId: string, phase: string, workflowType: string, stalenessMinutes: number }
  ],
  skipped: [
    { featureId: string, reason: "open-pr" | "active-branch" }
  ]
}
可选参数:
  • thresholdMinutes
    -- 过时时长阈值,默认值为10080(7天)
  • includeOneShot
    -- 是否将
    oneshot
    工作流纳入候选集合,默认值为
    true
  • force
    -- 干运行阶段无效;仅在应用阶段(步骤4)生效

Step 2: Display Candidate Table

步骤2:显示候选工作流表格

Render a table to the user so they can review what would be pruned. Use this format:
markdown
undefined
向用户渲染表格,以便其查看待清理内容。使用如下格式:
markdown
undefined

Prune Candidates (3)

待清理候选工作流(3个)

Feature IDTypePhaseStale (min)
feat-old-experimentfeatureimplementing14430
oneshot-typo-fixoneshotplan9120
debug-flaky-testdebuginvestigate8650
功能ID类型阶段过时时长(分钟)
feat-old-experimentfeatureimplementing14430
oneshot-typo-fixoneshotplan9120
debug-flaky-testdebuginvestigate8650

Skipped by Safeguards (2)

因保护机制被跳过的工作流(2个)

Feature IDReason
feat-active-propen-pr
feat-recent-workactive-branch

If `candidates.length === 0` AND `skipped.length === 0`, output:

> No stale workflows to prune. Pipeline is clean.

Then exit -- no further action.
功能ID原因
feat-active-propen-pr
feat-recent-workactive-branch

若`candidates.length === 0`且`skipped.length === 0`,输出:

> 无过时工作流需要清理,流水线已处于整洁状态。

随后退出——无需进一步操作。

Step 3: Prompt for Confirmation

步骤3:确认提示

Ask the user one of three choices:
proceed -- prune the listed candidates (skipped workflows stay) abort -- exit without changes force -- bypass safeguards and prune skipped workflows too
Wait for explicit user input. Do not auto-proceed.
向用户提供三个选项:
proceed -- 清理列出的候选工作流(被跳过的工作流保留) abort -- 退出且不做任何变更 force -- 绕过保护机制,同时清理被跳过的工作流
等待用户明确输入,请勿自动执行

Step 4a: Apply (proceed)

步骤4a:执行清理(proceed)

On
proceed
, invoke the same action with
dryRun: false
. Pass through
thresholdMinutes
and
includeOneShot
if the user set them in Step 1.
typescript
exarchos:exarchos_orchestrate({
  action: "prune_stale_workflows",
  args: {
    dryRun: false
  }
})
The response now includes a
pruned
array:
ts
{
  candidates: [...],
  skipped: [...],
  pruned: [
    { featureId: string, previousPhase: string }
  ]
}
Each entry in
pruned
corresponds to a workflow that transitioned to
cancelled
and emitted a
workflow.pruned
event.
用户选择
proceed
时,以
dryRun: false
调用相同操作。若用户在步骤1中设置了
thresholdMinutes
includeOneShot
,需同步传入。
typescript
exarchos:exarchos_orchestrate({
  action: "prune_stale_workflows",
  args: {
    dryRun: false
  }
})
此时响应会包含
pruned
数组:
ts
{
  candidates: [...],
  skipped: [...],
  pruned: [
    { featureId: string, previousPhase: string }
  ]
}
pruned
中的每一项对应一个已转为
cancelled
状态并生成
workflow.pruned
事件的工作流。

Step 4b: Apply (force)

步骤4b:执行清理(force)

On
force
, set
force: true
. Safeguards are bypassed but the bypass is recorded in the
workflow.pruned
event payload as
skippedSafeguards: [...]
so the audit trail is intact.
typescript
exarchos:exarchos_orchestrate({
  action: "prune_stale_workflows",
  args: {
    dryRun: false,
    force: true
  }
})
In force mode, workflows that were in the
skipped
list during dry-run are now eligible for pruning.
用户选择
force
时,设置
force: true
。保护机制会被绕过,但绕过操作会记录在
workflow.pruned
事件的
skippedSafeguards: [...]
字段中,确保审计轨迹完整。
typescript
exarchos:exarchos_orchestrate({
  action: "prune_stale_workflows",
  args: {
    dryRun: false,
    force: true
  }
})
在强制模式下,干运行阶段处于
skipped
列表中的工作流现在可被清理。

Step 4c: Apply (abort)

步骤4c:执行清理(abort)

On
abort
, exit without invoking the action a second time. The dry-run has not mutated any state.
用户选择
abort
时,退出且不再调用该操作。干运行未变更任何状态。

Step 5: Report Results

步骤5:结果报告

After the apply call returns, summarize the outcome:
markdown
undefined
执行调用返回后,汇总结果:
markdown
undefined

Prune Complete

清理完成

Pruned: 3 workflows transitioned to cancelled Skipped: 2 workflows preserved by safeguards Force bypass: no
已清理: 3个工作流已转为取消状态 已跳过: 2个工作流因保护机制被保留 强制绕过:

Pruned Workflows

已清理工作流

  • feat-old-experiment (was: implementing)
  • oneshot-typo-fix (was: plan)
  • debug-flaky-test (was: investigate)

If `force` was used, also list any safeguards that were bypassed:

```markdown
  • feat-old-experiment(原阶段:implementing)
  • oneshot-typo-fix(原阶段:plan)
  • debug-flaky-test(原阶段:investigate)

若使用了`force`,还需列出被绕过的保护机制:

```markdown

Safeguards Bypassed

被绕过的保护机制

  • feat-active-pr: open-pr
  • feat-recent-work: active-branch
undefined
  • feat-active-pr: open-pr
  • feat-recent-work: active-branch
undefined

Safeguards Explained

保护机制说明

Two safeguards run automatically in the orchestrate handler before each cancel:
SafeguardBehaviorReason key
Open PRSkip if
gh pr list --head <branch> --state open
returns any results
open-pr
Recent commitsSkip if
git log --since "24 hours ago" origin/<branch>
shows commits
active-branch
A workflow without a
branchName
in state (e.g., abandoned at ideate/plan before delegation) cannot have a PR or branch activity, so safeguards short-circuit and the workflow is eligible for pruning.
force: true
bypasses both checks but does not bypass the audit -- the bypassed safeguard names are recorded in the
workflow.pruned
event payload.
编排处理程序在每次取消操作前会自动运行两项保护机制:
保护机制行为原因标识
开放PR检测
gh pr list --head <branch> --state open
返回结果,则跳过该工作流
open-pr
近期提交检测
git log --since "24 hours ago" origin/<branch>
显示有提交,则跳过该工作流
active-branch
状态中无
branchName
的工作流(例如在委托前已停滞在ideate/plan阶段的工作流)无法检测PR或分支活动,因此保护机制会直接跳过,该工作流可被清理。
force: true
会绕过两项检查,但不会跳过审计——被绕过的保护机制名称会记录在
workflow.pruned
事件的负载中。

Error Handling

错误处理

  • No state directory: initialize an exarchos workflow first — there is nothing to prune.
  • gh
    /
    git
    not available:
    the safeguard checks short-circuit with errors. Verify no PRs are open manually, then re-run with
    force: true
    .
  • All workflows clean: report "No stale workflows to prune" and exit (see Example 3).
  • 无状态目录: 先初始化exarchos工作流——无内容可清理。
  • gh
    /
    git
    不可用:
    保护检查会因错误终止。手动确认无开放PR后,使用
    force: true
    重新运行。
  • 所有工作流已整洁: 报告“无过时工作流需要清理”并退出(见示例3)。

Anti-Patterns

反模式

Don'tDo Instead
Skip the dry-run stepAlways start with
dryRun: true
so the user sees candidates first
Auto-confirm without showing the tableRender the candidate table and wait for explicit user input
Use
force: true
by default
Reserve
force
for cases where the user has explicitly opted in
Manually call
cancel
for each stale workflow
Use this skill -- it batches the cancel loop and emits the
workflow.pruned
audit event
Run on every sessionPruning is a maintenance operation; run when pipeline accumulation is observable
请勿建议做法
跳过干运行步骤始终以
dryRun: true
启动,确保用户先查看候选工作流
不显示表格直接自动确认渲染候选工作流表格并等待用户明确输入
默认使用
force: true
仅在用户明确选择时使用
force
手动为每个过时工作流调用
cancel
使用该Skill——它会批量处理取消循环并生成
workflow.pruned
审计事件
每次会话都运行清理是维护操作;仅在流水线出现工作流累积时运行

Examples

示例

Example 1: Clean dry-run, user proceeds

示例1:干运行正常,用户选择继续

> prune
> prune

Prune Candidates (2)

待清理候选工作流(2个)

Feature IDTypePhaseStale (min)
feat-old-spikefeatureplan12880
oneshot-readme-tweakoneshotimplementing9700
功能ID类型阶段过时时长(分钟)
feat-old-spikefeatureplan12880
oneshot-readme-tweakoneshotimplementing9700

Skipped by Safeguards (0)

因保护机制被跳过的工作流(0个)

(none)
Proceed? (proceed/abort/force)
proceed
(无)
是否继续?(proceed/abort/force)
proceed

Prune Complete

清理完成

Pruned: 2 workflows transitioned to cancelled Skipped: 0 Force bypass: no
已清理: 2个工作流已转为取消状态 已跳过: 0个 强制绕过:

Pruned Workflows

已清理工作流

  • feat-old-spike (was: plan)
  • oneshot-readme-tweak (was: implementing)
undefined
  • feat-old-spike(原阶段:plan)
  • oneshot-readme-tweak(原阶段:implementing)
undefined

Example 2: Safeguard skip, user forces

示例2:保护机制跳过,用户选择强制清理

> prune
> prune

Prune Candidates (1)

待清理候选工作流(1个)

Feature IDTypePhaseStale (min)
feat-stale-no-prfeatureimplementing11200
功能ID类型阶段过时时长(分钟)
feat-stale-no-prfeatureimplementing11200

Skipped by Safeguards (1)

因保护机制被跳过的工作流(1个)

Feature IDReason
feat-stale-with-propen-pr
Proceed? (proceed/abort/force)
force
功能ID原因
feat-stale-with-propen-pr
是否继续?(proceed/abort/force)
force

Prune Complete

清理完成

Pruned: 2 workflows transitioned to cancelled Skipped: 0 Force bypass: yes
已清理: 2个工作流已转为取消状态 已跳过: 0个 强制绕过:

Pruned Workflows

已清理工作流

  • feat-stale-no-pr (was: implementing)
  • feat-stale-with-pr (was: implementing)
  • feat-stale-no-pr(原阶段:implementing)
  • feat-stale-with-pr(原阶段:implementing)

Safeguards Bypassed

被绕过的保护机制

  • feat-stale-with-pr: open-pr
undefined
  • feat-stale-with-pr: open-pr
undefined

Example 3: Empty pipeline

示例3:流水线无过时工作流

> prune

No stale workflows to prune. Pipeline is clean.
> prune

无过时工作流需要清理,流水线已处于整洁状态。

Schema Discovery

Schema 发现

For the canonical argument schema and any future fields, use:
typescript
exarchos:exarchos_orchestrate({
  action: "describe",
  actions: ["prune_stale_workflows"]
})
如需获取标准参数Schema及未来新增字段,使用:
typescript
exarchos:exarchos_orchestrate({
  action: "describe",
  actions: ["prune_stale_workflows"]
})

Exarchos Integration

Exarchos 集成

The
prune_stale_workflows
action emits two events per pruned workflow:
  • workflow.cancelled
    (auto-emitted by the underlying
    handleCancel
    path)
  • workflow.pruned
    (emitted by this handler with
    triggeredBy: 'manual'
    and optional
    skippedSafeguards
    )
Both are projected into the workflow state's
_events
array by the standard projection. Downstream views can filter on
workflow.pruned
to identify batch cleanups versus user-initiated cancels.
prune_stale_workflows
操作会为每个被清理的工作流生成两个事件:
  • workflow.cancelled
    (由底层
    handleCancel
    流程自动生成)
  • workflow.pruned
    (由该处理程序生成,包含
    triggeredBy: 'manual'
    及可选的
    skippedSafeguards
    字段)
两个事件都会被标准投影添加到工作流状态的
_events
数组中。下游视图可通过
workflow.pruned
过滤批量清理操作与用户主动发起的取消操作。