coding-agent-harness 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +661 -21
  3. package/LICENSE-EXCEPTION.md +37 -0
  4. package/README.md +33 -1
  5. package/README.zh-CN.md +23 -1
  6. package/SKILL.md +9 -8
  7. package/docs-release/architecture/overview.md +1 -1
  8. package/docs-release/architecture/overview.zh-CN.md +1 -1
  9. package/docs-release/architecture/system-explainer/01-system-overview.md +217 -0
  10. package/docs-release/architecture/system-explainer/02-module-dependency.md +257 -0
  11. package/docs-release/architecture/system-explainer/03-task-lifecycle.md +304 -0
  12. package/docs-release/architecture/system-explainer/04-check-and-governance.md +239 -0
  13. package/docs-release/architecture/system-explainer/05-data-flow.md +276 -0
  14. package/docs-release/architecture/system-explainer/06-preset-and-migration.md +303 -0
  15. package/docs-release/architecture/system-explainer/README.md +67 -0
  16. package/docs-release/architecture/system-explainer/en-US/01-system-overview.md +226 -0
  17. package/docs-release/architecture/system-explainer/en-US/02-module-dependency.md +263 -0
  18. package/docs-release/architecture/system-explainer/en-US/03-task-lifecycle.md +319 -0
  19. package/docs-release/architecture/system-explainer/en-US/04-check-and-governance.md +250 -0
  20. package/docs-release/architecture/system-explainer/en-US/05-data-flow.md +290 -0
  21. package/docs-release/architecture/system-explainer/en-US/06-preset-and-migration.md +323 -0
  22. package/docs-release/architecture/system-explainer/en-US/README.md +70 -0
  23. package/docs-release/guides/agent-installation.en-US.md +8 -7
  24. package/docs-release/guides/agent-installation.md +9 -7
  25. package/docs-release/guides/preset-development.md +26 -2
  26. package/docs-release/guides/task-state-machine.en-US.md +30 -13
  27. package/docs-release/guides/task-state-machine.md +30 -13
  28. package/examples/minimal-project/docs/09-PLANNING/TASKS/demo-task/INDEX.md +60 -0
  29. package/package.json +3 -2
  30. package/references/harness-ledger.md +1 -1
  31. package/scripts/commands/migration-command.mjs +30 -0
  32. package/scripts/commands/task-command.mjs +26 -25
  33. package/scripts/harness.mjs +7 -3
  34. package/scripts/lib/capability-registry.mjs +17 -21
  35. package/scripts/lib/check-module-parallel.mjs +9 -16
  36. package/scripts/lib/check-profiles.mjs +35 -81
  37. package/scripts/lib/check-task-contracts.mjs +13 -5
  38. package/scripts/lib/core-shared.mjs +55 -2
  39. package/scripts/lib/dashboard-data.mjs +126 -18
  40. package/scripts/lib/dashboard-workbench.mjs +80 -1
  41. package/scripts/lib/dashboard-writer.mjs +6 -2
  42. package/scripts/lib/git-status-summary.mjs +1 -1
  43. package/scripts/lib/governance-sync.mjs +180 -83
  44. package/scripts/lib/harness-core.mjs +1 -0
  45. package/scripts/lib/markdown-utils.mjs +33 -0
  46. package/scripts/lib/migration-planner.mjs +4 -6
  47. package/scripts/lib/phase-kind.mjs +50 -0
  48. package/scripts/lib/preset-engine.mjs +5 -8
  49. package/scripts/lib/preset-registry.mjs +188 -39
  50. package/scripts/lib/review-confirm-git-gate.mjs +1 -1
  51. package/scripts/lib/status-builder.mjs +88 -0
  52. package/scripts/lib/status-dashboard-renderer.mjs +7 -4
  53. package/scripts/lib/task-audit-metadata.mjs +385 -0
  54. package/scripts/lib/task-audit-migration.mjs +350 -0
  55. package/scripts/lib/task-completion-consistency.mjs +11 -1
  56. package/scripts/lib/task-lifecycle/create-task-helpers.mjs +67 -0
  57. package/scripts/lib/task-lifecycle/phase-sync.mjs +88 -0
  58. package/scripts/lib/task-lifecycle/review-confirm.mjs +40 -29
  59. package/scripts/lib/task-lifecycle/review-gates.mjs +13 -10
  60. package/scripts/lib/task-lifecycle/review-submission.mjs +63 -0
  61. package/scripts/lib/task-lifecycle/scaffold-provenance.mjs +49 -0
  62. package/scripts/lib/task-lifecycle/template-files.mjs +53 -0
  63. package/scripts/lib/task-lifecycle.mjs +114 -147
  64. package/scripts/lib/task-metadata.mjs +118 -0
  65. package/scripts/lib/task-review-model.mjs +54 -68
  66. package/scripts/lib/task-scanner.mjs +70 -143
  67. package/skills/preset-creator/references/complex-task-skeleton/brief.md +11 -0
  68. package/templates/AGENTS.md.template +7 -5
  69. package/templates/dashboard/assets/app-src/00-state.js +12 -0
  70. package/templates/dashboard/assets/app-src/10-router.js +3 -0
  71. package/templates/dashboard/assets/app-src/20-overview.js +7 -3
  72. package/templates/dashboard/assets/app-src/35-task-detail.js +46 -6
  73. package/templates/dashboard/assets/app-src/55-presets.js +375 -0
  74. package/templates/dashboard/assets/app-src/60-shared.js +3 -1
  75. package/templates/dashboard/assets/app-src/90-bindings.js +131 -0
  76. package/templates/dashboard/assets/app.css +583 -0
  77. package/templates/dashboard/assets/app.css.manifest.json +1 -0
  78. package/templates/dashboard/assets/app.js +578 -10
  79. package/templates/dashboard/assets/app.manifest.json +1 -0
  80. package/templates/dashboard/assets/css-src/00-foundation.css +4 -0
  81. package/templates/dashboard/assets/css-src/40-detail-modules-migration.css +62 -0
  82. package/templates/dashboard/assets/css-src/45-presets.css +516 -0
  83. package/templates/dashboard/assets/i18n.js +140 -2
  84. package/templates/planning/INDEX.md +87 -0
  85. package/templates/planning/brief.md +1 -1
  86. package/templates/planning/module_session_prompt.md +1 -0
  87. package/templates/planning/review.md +0 -18
  88. package/templates/planning/task_plan.md +4 -43
  89. package/templates/planning/visual_map.md +13 -9
  90. package/templates/planning/visual_map.simple.md +52 -0
  91. package/templates/reference/execution-workflow-standard.md +29 -2
  92. package/templates-zh-CN/AGENTS.md.template +7 -5
  93. package/templates-zh-CN/planning/INDEX.md +87 -0
  94. package/templates-zh-CN/planning/brief.md +1 -1
  95. package/templates-zh-CN/planning/module_session_prompt.md +1 -0
  96. package/templates-zh-CN/planning/review.md +0 -18
  97. package/templates-zh-CN/planning/task_plan.md +3 -63
  98. package/templates-zh-CN/planning/visual_map.md +14 -7
  99. package/templates-zh-CN/planning/visual_map.simple.md +48 -0
  100. package/templates-zh-CN/reference/execution-workflow-standard.md +31 -6
@@ -185,26 +185,26 @@ The agent must read `session.json` and `migrate-plan.json`, then migrate active
185
185
  After initialization or migration, agents should not manually copy task folders. Use lifecycle commands:
186
186
 
187
187
  ```bash
188
- harness new-task phase-2-lifecycle \
188
+ harness new-task \
189
189
  --title "Phase 2 task lifecycle" \
190
190
  --locale en-US \
191
191
  /path/to/project
192
192
 
193
- harness task-start phase-2-lifecycle \
193
+ harness task-start <task-id-from-new-task-output> \
194
194
  --message "Start lifecycle slice implementation" \
195
195
  /path/to/project
196
196
 
197
- harness task-log phase-2-lifecycle \
197
+ harness task-log <task-id-from-new-task-output> \
198
198
  --message "Completed CLI and template updates" \
199
199
  --evidence "command:TARGET:npm-test:passed" \
200
200
  /path/to/project
201
201
 
202
- harness review-confirm TASKS/phase-2-lifecycle \
202
+ harness review-confirm <task-id-from-new-task-output> \
203
203
  --reviewer "Human Reviewer" \
204
- --confirm phase-2-lifecycle \
204
+ --confirm <task-id-from-new-task-output> \
205
205
  /path/to/project
206
206
 
207
- harness task-complete phase-2-lifecycle \
207
+ harness task-complete <task-id-from-new-task-output> \
208
208
  --message "Verification loop completed" \
209
209
  /path/to/project
210
210
  ```
@@ -212,13 +212,14 @@ harness task-complete phase-2-lifecycle \
212
212
  Rules:
213
213
 
214
214
  - Do not manually copy task templates or create partial task folders. `harness check` enforces the file set created by `new-task`.
215
+ - `new-task --title "..."` generates a default ID like `YYYY-MM-DD-phase-2-task-lifecycle-a1b2c3d4` to reduce collisions when multiple people or agents create tasks in the same repository. Pass an explicit `<task-id>` only when a coordinator needs a stable compatibility ID.
215
216
  - `new-task --budget simple` creates `brief.md`, `task_plan.md`, `visual_map.md`, and `progress.md`.
216
217
  - `new-task` defaults to `standard` and creates the simple files plus `execution_strategy.md`, `findings.md`, `lesson_candidates.md`, and `review.md`.
217
218
  - `new-task --budget complex` creates the standard files plus `references/INDEX.md` and `artifacts/INDEX.md`.
218
219
  - Existing task directories are not overwritten. Renaming or continuing old tasks is a coordinator decision.
219
220
  - `task-start`, `task-block`, and `task-complete` only update lifecycle status and logs in `progress.md`.
220
221
  - `task-log` only appends execution records. Evidence uses `type:PATH:summary`, for example `command:TARGET:npm-test:passed`.
221
- - `review-confirm` appends a human review confirmation to `review.md` and a log entry to `progress.md`. It must reject open P0/P1/P2 findings marked `Open: yes` or `Blocks Release: yes`.
222
+ - `review-confirm` writes human review confirmation audit fields to the task `INDEX.md` through gated commits. It must reject open P0/P1/P2 findings marked `Open: yes` or `Blocks Release: yes`.
222
223
  - CLI-owned lifecycle and lesson commands auto-commit allowlisted writes in a clean Git root. Dirty state appears in `status` / dashboard warnings and blocks those mechanical commits. Agent-owned manual edits still need proactive commits; deferred commits must record the no-commit reason, owner, and next step.
223
224
  - `status --json` keeps old `task.state` for compatibility and adds `lifecycleState`, `reviewStatus`, `closeoutStatus`, and `stateConflicts`. `done` means implementation finished; it does not mean `closed`.
224
225
  - For human operation, start the local HTML workbench with `harness dev /path/to/project`. It binds to `127.0.0.1`, chooses a port automatically, opens the browser, and refreshes when docs change. In headless or CI contexts, use `harness dev --no-open /path/to/project`.
@@ -204,26 +204,26 @@ harness migrate-verify \
204
204
  初始化或迁移完成后,agent 不应手工复制任务目录。使用生命周期命令创建和推进任务:
205
205
 
206
206
  ```bash
207
- harness new-task phase-2-lifecycle \
207
+ harness new-task \
208
208
  --title "阶段二任务生命周期" \
209
209
  --locale zh-CN \
210
210
  /path/to/project
211
211
 
212
- harness task-start phase-2-lifecycle \
212
+ harness task-start <new-task 输出的 task-id> \
213
213
  --message "开始实现生命周期切片" \
214
214
  /path/to/project
215
215
 
216
- harness task-log phase-2-lifecycle \
216
+ harness task-log <new-task 输出的 task-id> \
217
217
  --message "完成 CLI 与模板更新" \
218
218
  --evidence "command:TARGET:npm-test:passed" \
219
219
  /path/to/project
220
220
 
221
- harness review-confirm TASKS/phase-2-lifecycle \
221
+ harness review-confirm <new-task 输出的 task-id> \
222
222
  --reviewer "Human Reviewer" \
223
- --confirm phase-2-lifecycle \
223
+ --confirm <new-task 输出的 task-id> \
224
224
  /path/to/project
225
225
 
226
- harness task-complete phase-2-lifecycle \
226
+ harness task-complete <new-task 输出的 task-id> \
227
227
  --message "验证闭环完成" \
228
228
  /path/to/project
229
229
  ```
@@ -232,6 +232,8 @@ harness task-complete phase-2-lifecycle \
232
232
 
233
233
  - 不要手工复制任务模板,也不要创建不完整任务目录。`harness check` 会按
234
234
  `new-task` 创建的预算文件集校验。
235
+ - `new-task --title "..."` 默认生成类似 `YYYY-MM-DD-phase-2-task-lifecycle-a1b2c3d4`
236
+ 的任务 ID,避免多人或多 agent 同仓协作时重名;只有需要固定兼容 ID 时才传显式 `<task-id>`。
235
237
  - `new-task --budget simple` 创建 `brief.md`、`task_plan.md`、`visual_map.md`
236
238
  和 `progress.md`。
237
239
  - `new-task` 默认 `standard`,创建 simple 文件,并额外创建
@@ -242,7 +244,7 @@ harness task-complete phase-2-lifecycle \
242
244
  - `task-start`、`task-block`、`task-complete` 只更新 `progress.md` 的生命周期状态和日志。
243
245
  - `task-log` 只追加执行记录;证据使用 `type:PATH:summary`,例如
244
246
  `command:TARGET:npm-test:passed`。
245
- - `review-confirm` 会向 `review.md` 追加人工审查确认,并向 `progress.md` 追加日志;如果存在 `Open: yes` 或 `Blocks Release: yes` 的开放 P0/P1/P2 finding,必须拒绝确认。
247
+ - `review-confirm` 会通过受控提交把人工确认审计字段写入任务 `INDEX.md`;如果存在 `Open: yes` 或 `Blocks Release: yes` 的开放 P0/P1/P2 finding,必须拒绝确认。
246
248
  - CLI-owned lifecycle 和 lesson 命令会在干净 Git root 中自动提交 allowlisted 写入;dirty 状态会出现在 `status` / dashboard 的警告里,并阻塞这些机械化提交。Agent 手工改动仍要主动提交,不能提交时记录 no-commit reason、owner 和下一步。
247
249
  - `status --json` 保留旧 `task.state` 用于兼容,并新增 `lifecycleState`、`reviewStatus`、`closeoutStatus` 和 `stateConflicts`。`done` 只表示实现完成,不等于 `closed`。
248
250
  - 人工操作入口使用本地 HTML workbench:`harness dev /path/to/project`。它会启动只绑定 `127.0.0.1` 的动态页面、自动选择端口、打开浏览器并随 docs 变更刷新。无 GUI 或 CI 场景使用 `harness dev --no-open /path/to/project`。
@@ -28,6 +28,29 @@ and `harness install-user` seed them into the user preset root, while
28
28
  `harness preset seed` for the user root or `harness preset seed --project <target>`
29
29
  for the project root when a preset root is missing or incomplete.
30
30
 
31
+ ## Dashboard Management
32
+
33
+ The Dashboard exposes a Presets view for the target project. Static dashboards
34
+ show a read-only catalog of discovered project, user, and bundled presets,
35
+ including source, purpose, compatible budgets, task kind, manifest path, and
36
+ resource counts.
37
+
38
+ Use the local dynamic Workbench when you want to manage presets from the web UI:
39
+
40
+ ```bash
41
+ harness dev /path/to/project
42
+ ```
43
+
44
+ In Workbench mode, the Presets view can check presets, install a local preset
45
+ directory, `.zip` archive, or bundled preset id into the project or user scope,
46
+ seed bundled presets into either scope, and uninstall project/user presets.
47
+ Bundled package presets are immutable from the Dashboard: they can be inspected,
48
+ checked, and used as install or seed sources, but not edited or deleted.
49
+
50
+ The CLI and filesystem remain canonical. The Dashboard calls the same preset
51
+ registry operations as `harness preset ...`; it does not store independent preset
52
+ state.
53
+
31
54
  ## Package Layout
32
55
 
33
56
  ```text
@@ -184,13 +207,14 @@ Supported evidence types:
184
207
  ```bash
185
208
  harness preset check ./my-preset
186
209
  harness preset install ./my-preset
210
+ harness preset install ./my-preset.zip
187
211
  harness preset install ./my-preset --project /path/to/project
188
212
  harness preset install legacy-migration --force
189
213
  harness preset seed
190
214
  harness preset seed --project /path/to/project
191
215
  harness preset list --json /path/to/project
192
216
  harness preset inspect custom-review --json /path/to/project
193
- harness new-task custom-review-task --preset custom-review --subject "API contracts" /path/to/project
217
+ harness new-task --title "Custom review task" --preset custom-review --subject "API contracts" /path/to/project
194
218
  harness preset uninstall custom-review
195
219
  ```
196
220
 
@@ -199,7 +223,7 @@ harness preset uninstall custom-review
199
223
  For every preset, prove both the manifest and downstream task behavior:
200
224
 
201
225
  1. Run `harness preset check ./my-preset`.
202
- 2. Install into an isolated HOME or disposable environment.
226
+ 2. Install the folder and, if distributing an archive, install the `.zip` into an isolated HOME or disposable environment.
203
227
  3. Create at least one task with `harness new-task --preset`.
204
228
  4. For reference bundles, create two different tasks from the same preset and verify both contain the same shared `references/` files and independent audit/evidence bundles.
205
229
  5. Run `harness status --json`, `harness task-index --json`, and `harness check --profile target-project <target>`.
@@ -5,7 +5,8 @@ Chinese mirror: `docs-release/guides/task-state-machine.md`
5
5
  Coding Agent Harness does not model task state as a single field. The Dashboard derives the visible lifecycle from multiple files:
6
6
 
7
7
  - `progress.md` stores raw `task.state` and execution evidence.
8
- - `review.md` stores Agent Review Submission, material findings, and Human Review Confirmation.
8
+ - `review.md` stores Agent Review Submission, material findings, and review evidence.
9
+ - `INDEX.md` stores Task Audit Metadata, including task creation and human review confirmation audit fields.
9
10
  - `lesson_candidates.md` records lesson candidate decisions and sedimentation routing.
10
11
  - `10-WALKTHROUGH/Closeout-SSoT.md` records closeout status and links walkthrough evidence.
11
12
  - Tombstone / supersede metadata records whether a task was soft-deleted, merged, archived, or replaced.
@@ -32,20 +33,37 @@ stateDiagram-v2
32
33
  finalized --> [*]
33
34
  ```
34
35
 
35
- `task-review` means the agent submitted a review packet. It does not mean human approval. `review-confirm` is the Human Review Confirmation gate. `task-complete` / closeout is not a substitute for review confirmation.
36
+ `task-review` means the agent submitted a review packet. It does not mean human approval. `review-confirm` is the human confirmation gate and writes its audit fields to `INDEX.md`. `task-complete` / closeout is not a substitute for review confirmation.
37
+
38
+ ## Phase Kind Map
39
+
40
+ `visual_map.md` is the machine-readable phase timeline. New phase tables may include `Kind`, `Exit Command`, and `Actor` columns:
41
+
42
+ | Kind | Purpose | Counts Toward Implementation Completion | Typical Exit |
43
+ | --- | --- | --- | --- |
44
+ | `init` | Scope, context, budget, and execution strategy. | no | `harness task-start <task-id>` |
45
+ | `execution` | Implementation, documentation, and verification slices. | yes | `harness task-phase <task-id> <phase-id> --state done --completion 100 --evidence present` |
46
+ | `gate` | Agent review submission, human confirmation, lesson routing, walkthrough, and closeout. | no | `harness task-review`, `harness review-confirm`, or `harness task-complete` |
47
+
48
+ Older phase tables without `Kind` remain valid and are treated as `execution`.
49
+ The Dashboard implementation score uses non-skipped `execution` phases only.
50
+ Gate phases explain the next lifecycle action and owner; they do not make a finished implementation look incomplete.
51
+ Agents may run `Exit Command` values with `Actor: agent`. `Actor: human` gates, especially `review-confirm`, require explicit human action.
36
52
 
37
53
  ## Derived State
38
54
 
39
55
  ```mermaid
40
56
  flowchart TB
41
57
  Progress["progress.md<br/>task.state + evidence"]
42
- Review["review.md<br/>Agent Review Submission + findings + Human Review Confirmation"]
58
+ Index["INDEX.md<br/>Task Audit Metadata"]
59
+ Review["review.md<br/>Agent Review Submission + findings + evidence"]
43
60
  Lessons["lesson_candidates.md<br/>decision + sedimentation route"]
44
61
  Closeout["Closeout-SSoT.md<br/>closeout row + walkthrough"]
45
62
  Tombstone["tombstone / supersede metadata"]
46
63
  Scanner["scanner"]
47
64
 
48
65
  Progress --> Scanner
66
+ Index --> Scanner
49
67
  Review --> Scanner
50
68
  Lessons --> Scanner
51
69
  Closeout --> Scanner
@@ -62,7 +80,7 @@ flowchart TB
62
80
  | Field | Source | Purpose |
63
81
  | --- | --- | --- |
64
82
  | `task.state` | `progress.md` | Raw execution stage. |
65
- | `reviewStatus` | `review.md` + findings + Human Review Confirmation | Separates missing review, agent-submitted review, blockers, and human confirmation. |
83
+ | `reviewStatus` | `INDEX.md` Task Audit Metadata + `review.md` findings/submission | Separates missing review, agent-submitted review, blockers, and human confirmation. |
66
84
  | `closeoutStatus` | `Closeout-SSoT.md` | Separates missing, pending, and closed closeout. |
67
85
  | `lifecycleState` | scanner-derived | Main Dashboard lifecycle meaning. |
68
86
  | `taskQueues[]` | scanner-derived | Which lifecycle queues include the task. A task can be visible in more than one governance queue. |
@@ -76,9 +94,9 @@ flowchart TB
76
94
  | Tombstone, superseded-by, archive, or abandoned marker exists | `soft-deleted-superseded` | Hidden by default, but preserved for audit and replacement tracing. |
77
95
  | Open P0-P2 finding, invalid transition, audit failure, or failed human-review gate | `blocked` | Cannot enter human confirmation until the blocker is fixed or waived. |
78
96
  | Standard / complex task is missing required files, sections, evidence, lesson decision, or review submission | `missing-materials` | Needs agent repair; not part of the human review queue. |
79
- | `task-review` was submitted, materials are ready, and Human Review Confirmation is missing | `review-submitted` | Truly waiting for human review. |
80
- | Human Review Confirmation exists, but closeout / ledger / lessons are not fully closed | `confirmed-finalization-pending` | Accountability moved to the reviewer, but governance closeout remains. |
81
- | Human Review Confirmation exists, and closeout / ledger / lesson routing are complete | `finalized` | Truly complete and traceable. |
97
+ | `task-review` was submitted, materials are ready, and `INDEX.md` does not show human confirmation | `review-submitted` | Truly waiting for human review. |
98
+ | `INDEX.md` shows human confirmation, but closeout / ledger / lessons are not fully closed | `confirmed-finalization-pending` | Accountability moved to the reviewer, but governance closeout remains. |
99
+ | `INDEX.md` shows human confirmation, and closeout / ledger / lesson routing are complete | `finalized` | Truly complete and traceable. |
82
100
  | `task.state = blocked` without a review blocker | `active-blocked` | Execution is blocked. |
83
101
  | `task.state = in_progress` | `active` | Work is active. |
84
102
  | `task.state = planned/not_started` | `ready` | Work has not started; not in human review by default. |
@@ -91,9 +109,9 @@ flowchart TB
91
109
  | `required` | Review document exists, but the packet is not ready for human review. |
92
110
  | `submitted` | An agent submitted a review packet. This is not human confirmation. |
93
111
  | `blocked-open-findings` | There is an open P0-P2 finding or a finding that blocks release / confirmation. |
94
- | `confirmed` | `Human Review Confirmation` exists. |
112
+ | `confirmed` | `INDEX.md` Task Audit Metadata has `Human Review Status: confirmed` and committed audit fields. |
95
113
 
96
- Agent self-review, subagent review, and coordinator review can only move a task toward `submitted`. Only `review-confirm` or an explicit Dashboard Workbench human confirmation writes `Human Review Confirmation`.
114
+ Agent self-review, subagent review, and coordinator review can only move a task toward `submitted`. Only `review-confirm` or an explicit Dashboard Workbench human confirmation writes the confirmation audit fields in `INDEX.md`.
97
115
 
98
116
  ## Lifecycle Queues
99
117
 
@@ -167,16 +185,15 @@ sequenceDiagram
167
185
  else accepted
168
186
  API->>Lifecycle: confirmTaskReview()
169
187
  Lifecycle->>Lifecycle: verify clean Git state, identity, hooks, allowlist
170
- Lifecycle->>Docs: write Human Review Confirmation
171
- Lifecycle->>Docs: append review-confirm log
172
- Lifecycle->>Lifecycle: commit allowlisted review/progress files
188
+ Lifecycle->>Docs: write confirmation fields to INDEX.md
189
+ Lifecycle->>Lifecycle: commit allowlisted INDEX.md
173
190
  Lifecycle->>Docs: record confirmation commit SHA + committed audit status
174
191
  API->>Scanner: regenerate dashboard snapshot
175
192
  API-->>UI: confirmed task
176
193
  end
177
194
  ```
178
195
 
179
- Strict rule: an agent can prepare review evidence and submit the task for review, but the task is not human-confirmed until the Human Review Confirmation block exists. Confirmation must use gated auto-commit: the CLI and Workbench reject dirty Git state, missing commit identity, hook/preflight failure, or writes outside the current task `review.md` / `progress.md` allowlist, and return recovery guidance.
196
+ Strict rule: an agent can prepare review evidence and submit the task for review, but the task is not human-confirmed until the task `INDEX.md` contains committed confirmation audit fields. Confirmation must use gated auto-commit: the CLI and Workbench reject dirty Git state, missing commit identity, hook/preflight failure, or writes outside the current task `INDEX.md` allowlist, and return recovery guidance.
180
197
 
181
198
  CLI-owned mechanical writes and agent-owned manual slices have different boundaries. `new-task`, `task-*`, `task-phase`, `module-step`, `review-confirm`, `lesson-sediment`, and `lesson-promote --apply` acquire a lock, restrict writes to an allowlist, and auto-commit in a clean Git root. When an agent manually edits code, templates, or task docs, it still needs to proactively commit after verification; if it cannot commit, it must record the no-commit reason, owner, and next step, and must not mix unrelated dirty changes into the task commit.
182
199
 
@@ -5,7 +5,8 @@ English mirror: `docs-release/guides/task-state-machine.en-US.md`
5
5
  Coding Agent Harness 的任务状态不是一个单字段。Dashboard 里看到的生命周期由多个文件共同推导:
6
6
 
7
7
  - `progress.md` 记录原始 `task.state` 和执行证据。
8
- - `review.md` 记录 Agent Review Submission、material findings 和 Human Review Confirmation。
8
+ - `review.md` 记录 Agent Review Submission、material findings 和审查证据。
9
+ - `INDEX.md` 记录任务审计元数据,包括任务创建和人工确认审计字段。
9
10
  - `lesson_candidates.md` 记录 lesson candidate 的人工判定和后续沉淀路由。
10
11
  - `10-WALKTHROUGH/Closeout-SSoT.md` 记录任务是否完成收口,并链接 walkthrough。
11
12
  - Tombstone / supersede 信息记录任务是否被软删除、合并、归档或替代。
@@ -32,20 +33,37 @@ stateDiagram-v2
32
33
  finalized --> [*]
33
34
  ```
34
35
 
35
- `task-review` 表示 Agent 提交审查材料包,不表示人工批准。`review-confirm` 才表示 Human Review Confirmation。`task-complete` / closeout 也不是 review confirmation 的替代品。
36
+ `task-review` 表示 Agent 提交审查材料包,不表示人工批准。`review-confirm` 才表示人工确认门禁,并把审计字段写入 `INDEX.md`。`task-complete` / closeout 也不是 review confirmation 的替代品。
37
+
38
+ ## 阶段类型地图
39
+
40
+ `visual_map.md` 是机器可读的阶段时间线。新的阶段表可以包含 `Kind`、`Exit Command` 和 `Actor` 三列:
41
+
42
+ | Kind | 作用 | 是否计入实现完成度 | 典型出口 |
43
+ | --- | --- | --- | --- |
44
+ | `init` | 范围、上下文、预算和执行策略。 | 否 | `harness task-start <task-id>` |
45
+ | `execution` | 实现、文档和验证切片。 | 是 | `harness task-phase <task-id> <phase-id> --state done --completion 100 --evidence present` |
46
+ | `gate` | Agent 提交审查、人工确认、lesson routing、walkthrough 和 closeout。 | 否 | `harness task-review`、`harness review-confirm` 或 `harness task-complete` |
47
+
48
+ 旧阶段表没有 `Kind` 也继续有效,默认按 `execution` 处理。
49
+ Dashboard 实现完成度只计算非 skipped 的 `execution` 阶段。
50
+ Gate 阶段用于解释下一步生命周期动作和责任人,不会让已完成的实现看起来未完成。
51
+ Agent 只能执行 `Actor: agent` 的 `Exit Command`。`Actor: human` 的 gate,尤其是 `review-confirm`,必须由人工明确执行。
36
52
 
37
53
  ## 派生状态
38
54
 
39
55
  ```mermaid
40
56
  flowchart TB
41
57
  Progress["progress.md<br/>task.state + evidence"]
42
- Review["review.md<br/>Agent Review Submission + findings + Human Review Confirmation"]
58
+ Index["INDEX.md<br/>Task Audit Metadata"]
59
+ Review["review.md<br/>Agent Review Submission + findings + evidence"]
43
60
  Lessons["lesson_candidates.md<br/>decision + sedimentation route"]
44
61
  Closeout["Closeout-SSoT.md<br/>closeout row + walkthrough"]
45
62
  Tombstone["tombstone / supersede metadata"]
46
63
  Scanner["scanner"]
47
64
 
48
65
  Progress --> Scanner
66
+ Index --> Scanner
49
67
  Review --> Scanner
50
68
  Lessons --> Scanner
51
69
  Closeout --> Scanner
@@ -62,7 +80,7 @@ flowchart TB
62
80
  | 字段 | 来源 | 作用 |
63
81
  | --- | --- | --- |
64
82
  | `task.state` | `progress.md` | 原始执行阶段。 |
65
- | `reviewStatus` | `review.md` + findings + Human Review Confirmation | 区分缺审查、Agent 已提交审查、阻塞、人工确认。 |
83
+ | `reviewStatus` | `INDEX.md` Task Audit Metadata + `review.md` findings/submission | 区分缺审查、Agent 已提交审查、阻塞、人工确认。 |
66
84
  | `closeoutStatus` | `Closeout-SSoT.md` | 区分收口缺失、待处理、已关闭。 |
67
85
  | `lifecycleState` | scanner 派生 | Dashboard 的主生命周期语义。 |
68
86
  | `taskQueues[]` | scanner 派生 | 任务属于哪些生命周期队列。一个任务可同时在多个治理队列中可见。 |
@@ -76,9 +94,9 @@ flowchart TB
76
94
  | 有 tombstone、superseded-by、archive 或 abandoned 标记 | `soft-deleted-superseded` | 默认隐藏,但保留审计和替代链。 |
77
95
  | 有 open P0-P2 finding、非法状态转换、审计失败或人审门禁失败 | `blocked` | 不能进入人工确认,必须先修 blocker 或记录 waiver。 |
78
96
  | 标准/复杂任务缺必需文件、章节、证据、lesson decision 或 review submission | `missing-materials` | 需要 Agent 补材料,不属于人审队列。 |
79
- | 已执行 `task-review`,材料齐全,且未 Human Review Confirmation | `review-submitted` | 真正等待人审。 |
80
- | Human Review Confirmation,但 closeout / ledger / lessons 仍未全部收口 | `confirmed-finalization-pending` | 责任已转移给确认人,但治理收口仍待完成。 |
81
- | Human Review Confirmation,且 closeout / ledger / lesson routing 完成 | `finalized` | 真正完成,可只读追溯。 |
97
+ | 已执行 `task-review`,材料齐全,且 `INDEX.md` 尚未显示人工确认 | `review-submitted` | 真正等待人审。 |
98
+ | `INDEX.md` 已显示人工确认,但 closeout / ledger / lessons 仍未全部收口 | `confirmed-finalization-pending` | 责任已转移给确认人,但治理收口仍待完成。 |
99
+ | `INDEX.md` 已显示人工确认,且 closeout / ledger / lesson routing 完成 | `finalized` | 真正完成,可只读追溯。 |
82
100
  | `task.state = blocked` 但没有 review blocker | `active-blocked` | 执行阻塞。 |
83
101
  | `task.state = in_progress` | `active` | 执行中。 |
84
102
  | `task.state = planned/not_started` | `ready` | 准备中,默认不进入人审队列。 |
@@ -91,9 +109,9 @@ flowchart TB
91
109
  | `required` | 有 review 文档,但还没有足够材料可提交人审。 |
92
110
  | `submitted` | Agent 已提交审查材料包;这不是人工确认。 |
93
111
  | `blocked-open-findings` | 有 open P0-P2 finding,或 finding 阻塞发布 / 确认。 |
94
- | `confirmed` | 已写入 `Human Review Confirmation`。 |
112
+ | `confirmed` | `INDEX.md` Task Audit Metadata 包含 `Human Review Status: confirmed` 和已提交审计字段。 |
95
113
 
96
- Agent 自查、subagent 审查和 coordinator 审查都只能让任务接近 `submitted`。只有 `review-confirm` 或 Workbench 的明确人工确认动作会写入 `Human Review Confirmation`。
114
+ Agent 自查、subagent 审查和 coordinator 审查都只能让任务接近 `submitted`。只有 `review-confirm` 或 Workbench 的明确人工确认动作会把确认审计字段写入 `INDEX.md`。
97
115
 
98
116
  ## 生命周期队列
99
117
 
@@ -174,16 +192,15 @@ sequenceDiagram
174
192
  else accepted
175
193
  API->>Lifecycle: confirmTaskReview()
176
194
  Lifecycle->>Lifecycle: verify Git clean, identity, hooks, allowlist
177
- Lifecycle->>Docs: write Human Review Confirmation
178
- Lifecycle->>Docs: append review-confirm log
179
- Lifecycle->>Lifecycle: commit allowlisted review/progress files
195
+ Lifecycle->>Docs: write confirmation fields to INDEX.md
196
+ Lifecycle->>Lifecycle: commit allowlisted INDEX.md
180
197
  Lifecycle->>Docs: record confirmation commit SHA + committed audit status
181
198
  API->>Scanner: regenerate dashboard snapshot
182
199
  API-->>UI: confirmed task
183
200
  end
184
201
  ```
185
202
 
186
- 严格规则:Agent 可以准备 review evidence,也可以提交审查;但任务只有在 Human Review Confirmation block 存在后,才算人工确认。确认动作必须通过 gated auto-commit:Git 状态不干净、提交身份缺失、hook/preflight 失败,或待写文件超出当前任务 `review.md` / `progress.md` 白名单时,CLI 和 Workbench 都会拒绝并返回恢复建议。
203
+ 严格规则:Agent 可以准备 review evidence,也可以提交审查;但任务只有在任务 `INDEX.md` 包含已提交的确认审计字段后,才算人工确认。确认动作必须通过 gated auto-commit:Git 状态不干净、提交身份缺失、hook/preflight 失败,或待写文件超出当前任务 `INDEX.md` 白名单时,CLI 和 Workbench 都会拒绝并返回恢复建议。
187
204
 
188
205
  CLI-owned 机械写入和 agent-owned 手工切片是两条边界。`new-task`、`task-*`、`task-phase`、`module-step`、`review-confirm`、`lesson-sediment` 和 `lesson-promote --apply` 会在干净 Git root 中加锁、限制写入范围并自动提交。Agent 手工编辑代码、模板或任务文档时仍要在验证后主动提交;无法提交时必须记录 no-commit reason、owner 和下一步,不能把 unrelated dirty changes 混入任务提交。
189
206
 
@@ -0,0 +1,60 @@
1
+ # Demo task - Task Package Index
2
+
3
+ Task Contract: harness-task/v1
4
+
5
+ ## Task Identity
6
+
7
+ | Field | Value |
8
+ | --- | --- |
9
+ | Task ID | `demo-task` |
10
+ | Budget | `standard` |
11
+ | Preset | `none` |
12
+ | Module | `n/a` |
13
+ | Long-running | `no` |
14
+ | Created | 2026-05-25 |
15
+
16
+ ## Task Audit Metadata
17
+
18
+ | Field | Value |
19
+ | --- | --- |
20
+ | Created By | historical-backfill |
21
+ | Created At | 2026-05-25 |
22
+ | Command Shape | n/a |
23
+ | Budget | standard |
24
+ | Template Source | examples/minimal-project historical fixture |
25
+ | Task Creator | n/a |
26
+ | Task Creator Source | legacy-unavailable |
27
+ | Human Review Status | not-confirmed |
28
+ | Confirmation ID | n/a |
29
+ | Confirmed At | n/a |
30
+ | Reviewer | n/a |
31
+ | Reviewer Email | n/a |
32
+ | Confirm Text | n/a |
33
+ | Evidence Checked | n/a |
34
+ | Review Commit SHA | n/a |
35
+ | Audit Source | migrated-legacy-scaffold |
36
+ | Audit Status | migrated |
37
+ | Exception Reason | Existing demo task predates scaffold provenance enforcement. |
38
+ | Message | n/a |
39
+ | Migration Status | migrated |
40
+ | Migrated From | brief.md#Scaffold Provenance |
41
+ | Legacy Extra Fields | {} |
42
+ | Migration Notes | example fixture backfilled to INDEX audit metadata |
43
+
44
+ ## Core Contract Files
45
+
46
+ | File | Purpose |
47
+ | --- | --- |
48
+ | `brief.md` | Human-readable task summary and context entry. |
49
+ | `task_plan.md` | Current task goal, scope, selected budget, acceptance, and operating decisions. |
50
+ | `visual_map.md` | Phase map, evidence status, next lifecycle commands, and supporting diagrams. |
51
+ | `progress.md` | Execution log, verification evidence, decisions, and handoff notes. |
52
+
53
+ ## Standard Task Files
54
+
55
+ | File | Purpose |
56
+ | --- | --- |
57
+ | `execution_strategy.md` | Execution mode, ownership, conflict control, and evidence strategy. |
58
+ | `findings.md` | Findings, research notes, accepted risks, and unresolved questions. |
59
+ | `lesson_candidates.md` | Task-local lesson candidate decisions before closeout. |
60
+ | `review.md` | Agent review submission, adversarial review, findings, evidence, and routing. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coding-agent-harness",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Document governance kernel for long-running coding agents.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -44,6 +44,7 @@
44
44
  "CHANGELOG.md",
45
45
  "SKILL.md",
46
46
  "LICENSE",
47
+ "LICENSE-EXCEPTION.md",
47
48
  "references/",
48
49
  "skills/",
49
50
  "presets/",
@@ -56,5 +57,5 @@
56
57
  "engines": {
57
58
  "node": ">=18"
58
59
  },
59
- "license": "MIT"
60
+ "license": "AGPL-3.0-or-later"
60
61
  }
@@ -48,7 +48,7 @@ Harness Ledger 不记录:
48
48
  触发任务生命周期变化时,优先使用 CLI:
49
49
 
50
50
  ```bash
51
- harness new-task <task-id>
51
+ harness new-task --title "<title>"
52
52
  harness task-start <task-id>
53
53
  harness task-phase <task-id> <phase-id> --state done
54
54
  harness task-review <task-id>
@@ -3,8 +3,38 @@ import {
3
3
  runMigration,
4
4
  verifyMigrationSession,
5
5
  } from "../lib/harness-core.mjs";
6
+ import {
7
+ applyTaskAuditIndexMigration,
8
+ planTaskAuditIndexMigration,
9
+ } from "../lib/task-audit-migration.mjs";
6
10
 
7
11
  export function runMigrationCommand(command, { args, takeFlag, takeOption, targetArg }) {
12
+ if (command === "migrate-task-audit-index") {
13
+ const json = takeFlag("--json");
14
+ const apply = takeFlag("--apply");
15
+ const planOnly = takeFlag("--plan");
16
+ try {
17
+ const result = apply && !planOnly
18
+ ? applyTaskAuditIndexMigration(targetArg())
19
+ : planTaskAuditIndexMigration(targetArg());
20
+ if (json) {
21
+ console.log(JSON.stringify(result, null, 2));
22
+ } else {
23
+ console.log(`Task audit INDEX migration ${result.result}: ${result.target}`);
24
+ console.log(`actions: ${result.summary.actions}`);
25
+ console.log(`legacy audit blocks: ${result.summary.legacyAuditBlocks}`);
26
+ console.log(`failures: ${result.summary.failures}`);
27
+ for (const action of result.actions || []) console.log(`- ${action.taskId}: ${action.legacyBlocks.join(", ")}`);
28
+ for (const failure of result.failures || []) console.error(`Failure: ${failure.taskId}: ${failure.failure}`);
29
+ }
30
+ process.exit(result.failures?.length ? 1 : 0);
31
+ } catch (error) {
32
+ if (json && error.plan) console.error(JSON.stringify(error.plan, null, 2));
33
+ else console.error(error.message);
34
+ process.exit(1);
35
+ }
36
+ }
37
+
8
38
  if (command === "migrate-plan") {
9
39
  const json = takeFlag("--json");
10
40
  const limit = Number.parseInt(takeOption("--limit", "20"), 10) || 20;
@@ -1,4 +1,3 @@
1
- import fs from "node:fs";
2
1
  import {
3
2
  confirmTaskReview,
4
3
  createTask,
@@ -28,12 +27,7 @@ export function runTaskCommand(command, { args, takeFlag, takeOption, targetArg
28
27
  const longRunning = takeFlag("--long-running");
29
28
  try {
30
29
  const parsed = parseNewTaskArgs(args, { preset, fromSession });
31
- const taskId = parsed.taskId;
32
- if (!taskId) {
33
- console.error("Missing task id");
34
- process.exit(2);
35
- }
36
- console.log(JSON.stringify(createTask(parsed.target, taskId, { title, locale, dryRun, moduleKey, budget, longRunning, preset, fromSession, presetArgs: parsed.presetArgs }), null, 2));
30
+ console.log(JSON.stringify(createTask(parsed.target, parsed.taskId, { title, locale, dryRun, moduleKey, budget, longRunning, preset, fromSession, presetArgs: parsed.presetArgs, automaticTaskId: parsed.automaticTaskId }), null, 2));
37
31
  } catch (error) {
38
32
  console.error(error.message);
39
33
  process.exit(1);
@@ -229,20 +223,15 @@ export function runTaskCommand(command, { args, takeFlag, takeOption, targetArg
229
223
  throw new Error(`Unsupported task command: ${command}`);
230
224
  }
231
225
 
232
- function parseNewTaskArgs(args, { preset = "", fromSession = "" } = {}) {
226
+ function parseNewTaskArgs(args, { preset = "" } = {}) {
233
227
  const values = [...args];
234
- let taskId = "";
235
- if (!fromSession) {
236
- taskId = values.shift() || "";
237
- } else if (values.length > 0 && !values[0].startsWith("-") && !(values.length === 1 && fs.existsSync(values[0]))) {
238
- taskId = values.shift();
239
- }
240
228
  const presetPackage = preset ? readPresetPackageForNewTask(preset, values) : null;
241
- if (!taskId && fromSession) taskId = presetPackage?.task?.defaultTaskId || "harness-v1-migration";
242
- const parsed = splitPresetArgsAndTarget(values, presetPackage);
229
+ const parsed = splitPresetArgsAndPositionals(values, presetPackage);
230
+ const resolved = resolveNewTaskPositionals(parsed.positionals);
243
231
  return {
244
- taskId,
245
- target: parsed.target || ".",
232
+ taskId: resolved.taskId,
233
+ target: resolved.target || ".",
234
+ automaticTaskId: !resolved.taskId,
246
235
  presetArgs: parsed.presetArgs,
247
236
  };
248
237
  }
@@ -275,9 +264,9 @@ function presetDiscoveryTargetCandidates(values) {
275
264
  return candidates;
276
265
  }
277
266
 
278
- function splitPresetArgsAndTarget(values, presetPackage) {
267
+ function splitPresetArgsAndPositionals(values, presetPackage) {
279
268
  const presetArgs = [];
280
- const targetCandidates = [];
269
+ const positionals = [];
281
270
  const declaredFlags = new Map(Object.values(presetPackage?.inputs || {}).filter((input) => input.flag).map((input) => [input.flag, input]));
282
271
  for (let index = 0; index < values.length; index += 1) {
283
272
  const value = values[index];
@@ -295,18 +284,30 @@ function splitPresetArgsAndTarget(values, presetPackage) {
295
284
  index += 1;
296
285
  }
297
286
  } else {
298
- targetCandidates.push(value);
287
+ positionals.push(value);
299
288
  }
300
289
  }
301
- if (targetCandidates.length > 1) {
302
- throw new Error(`Too many positional arguments for new-task: ${targetCandidates.join(", ")}`);
303
- }
304
290
  return {
305
- target: targetCandidates[0] || "",
291
+ positionals,
306
292
  presetArgs,
307
293
  };
308
294
  }
309
295
 
296
+ function isPathLikePositional(value) {
297
+ return value === "." || value === ".." || value.startsWith("/") || value.startsWith("~/") || value.includes("/") || value.includes("\\");
298
+ }
299
+
300
+ function resolveNewTaskPositionals(positionals) {
301
+ if (positionals.length === 0) return { taskId: "", target: "" };
302
+ if (positionals.length === 1) {
303
+ const [value] = positionals;
304
+ if (isPathLikePositional(value)) return { taskId: "", target: value };
305
+ return { taskId: value, target: "" };
306
+ }
307
+ if (positionals.length === 2) return { taskId: positionals[0], target: positionals[1] };
308
+ throw new Error(`Too many positional arguments for new-task: ${positionals.join(", ")}`);
309
+ }
310
+
310
311
  function formatTaskCommandError(error) {
311
312
  const lines = [error.message];
312
313
  if (Array.isArray(error.recovery) && error.recovery.length > 0) {
@@ -87,16 +87,17 @@ Usage:
87
87
  harness init [--dry-run] [--locale zh-CN|en-US] [--capabilities core,dashboard] [--add-npm-scripts] [target]
88
88
  harness add-capability <name> [--dry-run] [--locale zh-CN|en-US] [target]
89
89
  harness migrate-plan [--json] [--limit n] [target]
90
+ harness migrate-task-audit-index [--plan] [--apply] [--json] [target]
90
91
  harness migrate-run [--locale zh-CN|en-US] [--assume-locale] [--allow-dirty] [--plan-only] [--out-dir folder] [--session-dir folder] [target]
91
92
  harness migrate-verify [--json] [--full-cutover] <session.json>
92
93
  harness governance rebuild [--dry-run] [--archive] [--apply] [target]
93
94
  harness preset list [--json] [target]
94
95
  harness preset inspect <id> [--json] [target]
95
96
  harness preset check <id> [--json] [target]
96
- harness preset install <path-or-builtin-id> [--project] [--force] [--json] [target]
97
+ harness preset install <folder|zip|builtin-id> [--project] [--force] [--json] [target]
97
98
  harness preset seed [--project] [--force] [--dry-run] [--json] [target]
98
99
  harness preset uninstall <id> [--project] [--json] [target]
99
- harness new-task <task-id> [--module key] [--budget simple|standard|complex] [--preset id] [--from-session session.json] [--long-running] [--title title] [--locale zh-CN|en-US] [--dry-run] [target]
100
+ harness new-task [task-id] [--module key] [--budget simple|standard|complex] [--preset id] [--from-session session.json] [--long-running] [--title title] [--locale zh-CN|en-US] [--dry-run] [target]
100
101
  harness task-start <task-id> [--message text] [target]
101
102
  harness task-phase <task-id> <phase-id> [--state done] [--completion 100] [--evidence present] [target]
102
103
  harness task-log <task-id> --message text [--evidence type:PATH:summary] [target]
@@ -127,6 +128,9 @@ Preset discovery:
127
128
  "harness init" seeds bundled presets into the target project. "harness
128
129
  install-user" and npm postinstall seed bundled presets into the user root.
129
130
  Use "harness preset seed" to repair or re-run preset seeding.
131
+ Use "harness preset install" with a local preset folder, .zip archive, or
132
+ bundled preset id. Preset archives must contain preset.yaml at the archive
133
+ root or inside one top-level folder.
130
134
  Use "harness preset list --json" to see available presets, their source,
131
135
  purpose, compatible budgets, and manifest path. Use "harness preset inspect
132
136
  <id> --json" for the full preset manifest summary.
@@ -224,7 +228,7 @@ if (command === "help" || command === "--help" || command === "-h") {
224
228
  console.error(error.message);
225
229
  process.exit(1);
226
230
  }
227
- } else if (["migrate-plan", "migrate-run", "migrate-verify"].includes(command)) {
231
+ } else if (["migrate-plan", "migrate-run", "migrate-verify", "migrate-task-audit-index"].includes(command)) {
228
232
  runMigrationCommand(command, { args, takeFlag, takeOption, targetArg });
229
233
  } else if (command === "governance") {
230
234
  const subcommand = args.shift() || "";