@hunter-harness/workflow-harness 0.2.67 → 0.2.69
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.
- package/harness/bundles/general/claude-code/.harness-build.json +1 -1
- package/harness/bundles/general/claude-code/contracts/workflow-policy.json +401 -88
- package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/claude-code/harness-plan/reference.md +1 -1
- package/harness/bundles/general/claude-code/harness-pull/SKILL.md +73 -0
- package/harness/bundles/general/claude-code/harness-push/SKILL.md +73 -0
- package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/scripts/harness_plan_finalize.py +119 -0
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/contracts/workflow-policy.json +401 -88
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/codebuddy/harness-plan/reference.md +1 -1
- package/harness/bundles/general/codebuddy/harness-pull/SKILL.md +55 -0
- package/harness/bundles/general/codebuddy/harness-push/SKILL.md +55 -0
- package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/scripts/harness_plan_finalize.py +119 -0
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/contracts/workflow-policy.json +401 -88
- package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/codex/harness-plan/reference.md +1 -1
- package/harness/bundles/general/codex/harness-pull/SKILL.md +55 -0
- package/harness/bundles/general/codex/harness-push/SKILL.md +55 -0
- package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/codex/scripts/harness_plan_finalize.py +119 -0
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/contracts/workflow-policy.json +401 -88
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/cursor/harness-plan/reference.md +1 -1
- package/harness/bundles/general/cursor/harness-pull/SKILL.md +55 -0
- package/harness/bundles/general/cursor/harness-push/SKILL.md +55 -0
- package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/cursor/scripts/harness_plan_finalize.py +119 -0
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/contracts/workflow-policy.json +401 -88
- package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/claude-code/harness-plan/reference.md +1 -1
- package/harness/bundles/java/claude-code/harness-pull/SKILL.md +73 -0
- package/harness/bundles/java/claude-code/harness-push/SKILL.md +73 -0
- package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/scripts/harness_plan_finalize.py +119 -0
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/contracts/workflow-policy.json +401 -88
- package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/codebuddy/harness-plan/reference.md +1 -1
- package/harness/bundles/java/codebuddy/harness-pull/SKILL.md +55 -0
- package/harness/bundles/java/codebuddy/harness-push/SKILL.md +55 -0
- package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/scripts/harness_plan_finalize.py +119 -0
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/contracts/workflow-policy.json +401 -88
- package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/codex/harness-plan/reference.md +1 -1
- package/harness/bundles/java/codex/harness-pull/SKILL.md +55 -0
- package/harness/bundles/java/codex/harness-push/SKILL.md +55 -0
- package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/codex/scripts/harness_plan_finalize.py +119 -0
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/contracts/workflow-policy.json +401 -88
- package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/cursor/harness-plan/reference.md +1 -1
- package/harness/bundles/java/cursor/harness-pull/SKILL.md +55 -0
- package/harness/bundles/java/cursor/harness-push/SKILL.md +55 -0
- package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/cursor/scripts/harness_plan_finalize.py +119 -0
- package/harness/manifests/general/claude-code.json +27 -17
- package/harness/manifests/general/codebuddy.json +27 -17
- package/harness/manifests/general/codex.json +27 -17
- package/harness/manifests/general/cursor.json +27 -17
- package/harness/manifests/java/claude-code.json +29 -19
- package/harness/manifests/java/codebuddy.json +29 -19
- package/harness/manifests/java/codex.json +29 -19
- package/harness/manifests/java/cursor.json +29 -19
- package/hunter-workflow-family.json +11 -7
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ name: harness-plan
|
|
|
3
3
|
description: 将需求转化为设计文档+实施计划+完整测试场景表,必须在编码前完成。仅当用户显式调用 /harness-plan 或明确要求进入
|
|
4
4
|
Harness 规划阶段时使用;不得因用户描述需求就自动触发。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=99e00f374c938811; overlay=java; agent=codex; do not edit -->
|
|
7
7
|
# harness-plan — 需求规划
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -66,7 +66,7 @@ description: 将需求转化为设计文档+实施计划+完整测试场景表
|
|
|
66
66
|
| 阶段 | 动作 |
|
|
67
67
|
|------|------|
|
|
68
68
|
| 0 | 用当前解释器运行 `harness_runtime.py doctor`,后续消费绝对 argv;git status;脏工作区 → baseline 隔离 + `decision`,不询问 |
|
|
69
|
-
| 0.5 | 确定英文 `change-name` 后,根据需求生成一次简洁的中文展示标题(建议 6~24 个可见字符,保留必要产品名),执行 `harness_context.py prepare --phase plan --executor <tool> [--change <id>] --title "<中文标题>" --json`;英文名继续作为目录与稳定标识。立即运行一次 `harness_state.py capture --project . --change-dir "<executionRoot>" --json`,把此时 HEAD 固定为不可变 `changeBase`。以其唯一 change/executionRoot 初始化 plan-run-id 与 attempt(首次为 1
|
|
69
|
+
| 0.5 | 确定英文 `change-name` 后,根据需求生成一次简洁的中文展示标题(建议 6~24 个可见字符,保留必要产品名),执行 `harness_context.py prepare --phase plan --executor <tool> [--change <id>] --title "<中文标题>" --json`;英文名继续作为目录与稳定标识。立即运行一次 `harness_state.py capture --project . --change-dir "<executionRoot>" --json`,把此时 HEAD 固定为不可变 `changeBase`。以其唯一 change/executionRoot 初始化 plan-run-id 与 attempt(首次为 1);run-id 必须小写字母开头(v2 identity 规则,裸 UUID 有 10/16 概率数字开头被拒)——统一用 `plan_<uuid>` 形状(contracts `createPlanRunId()`),用同一身份追加 `phase.start`;从第一条知识查询起保留事件证据,并在 finalizer 中复用该身份 |
|
|
70
70
|
| 0.6 | 使用 `classify` 返回的默认阶段和项目能力生成 `plannedPhases`,向用户用中文说明可选阶段;确认后运行 `harness_context.py configure-plan --project . --change <id> --phases "plan,run,...,archive" --operator <tool> --reason "<中文原因>" --json`。无 Git 或不需要提交时不得加入 `submit`;快速迭代默认 `plan,run,archive`。省略项由脚本写入 `skippedPhases`,不得伪造阶段事件 |
|
|
71
71
|
| 1 | 直接执行一次 `npx hunter-harness knowledge query "<用户需求原文>" --limit 10 --json`。这是唯一执行入口,不扫描技能目录、不查找其他脚本;失败记 `issue` 并继续,不建立本地索引或离线回退 |
|
|
72
72
|
| 2 | 歧义优先检查 + 复杂度分级;先确认会改变实现方向的语义歧义 |
|
|
@@ -299,7 +299,7 @@ status: approved
|
|
|
299
299
|
|
|
300
300
|
> 如果 frontmatter 缺失,后续 run/test/review/submit/archive 不得依赖模型猜测 change-name。
|
|
301
301
|
|
|
302
|
-
4. **初始化结构化事件**:确定 change-name 后,立即生成稳定的 `<plan-run-id
|
|
302
|
+
4. **初始化结构化事件**:确定 change-name 后,立即生成稳定的 `<plan-run-id>`(必须小写字母开头:v2 identity 规则,裸 UUID 有 10/16 概率数字开头被拒——统一用 `plan_<uuid>` 形状,contracts `createPlanRunId()`;同一次 plan 尝试内不得改变;首次 `<attempt>` 为 `1`),运行 `harness_events.py append --change-dir ... --phase plan --type phase.start --run-id <plan-run-id> --attempt <attempt>`。finalizer 必须复用完全相同的 `--run-id` / `--attempt`,否则 verify 会按生命周期身份 fail-closed。脚本负责建立父目录和 `events.ndjson`;执行日志在 `phase.end` 时由完整事件流渲染,任何阶段都不得直接用 Write/Edit 维护该投影。
|
|
303
303
|
|
|
304
304
|
5. **保存计划文件**:计划文件包含 YAML frontmatter(含 change-name),保存到:
|
|
305
305
|
- `.harness/changes/<change-name>/plans/<change-name>-plan.md`(简洁任务表)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-pull
|
|
3
|
+
description: 从 Hunter Platform 下拉配置/规则/架构/指令(及显式来源分支的分支文件恢复)。仅当用户显式调用
|
|
4
|
+
/harness-pull 或明确说'从平台拉取/恢复'时使用;不得自动触发。
|
|
5
|
+
---
|
|
6
|
+
<!-- generated by harness_deploy.py; core=99e00f374c938811; overlay=java; agent=codex; do not edit -->
|
|
7
|
+
# harness-pull — 从 Hunter Platform 下拉与恢复
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
从 Hunter Platform 下拉远端配置、规则、架构和指令,或按显式来源分支恢复分支受管文件。本 skill 只负责理解意图、展示预览和收集确认;冲突判断、哈希校验与本地事务由 CLI/core 完成。
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
仅当用户显式调用 `/harness-pull`(或明确说"从平台拉取/恢复")时执行。日常刷新元数据请走 `harness-sync`,不是本 skill。
|
|
16
|
+
|
|
17
|
+
## 前置条件
|
|
18
|
+
|
|
19
|
+
- 远端同步已配置:`HUNTER_REMOTE_SYNC_URL`、`HUNTER_REMOTE_SYNC_TOKEN`、`HUNTER_REMOTE_SYNC_ACTOR_ID`。缺失时 CLI 固定 fail closed(`PUSH_PULL_CLI_UNAVAILABLE`)。
|
|
20
|
+
- 分支文件恢复必须显式 `--scope branch_files --branch <来源分支>`;归档不出现在常规下拉范围(单个归档 ZIP 经 Platform 变更记录单独下载)。
|
|
21
|
+
|
|
22
|
+
## 交互流程
|
|
23
|
+
|
|
24
|
+
1. **选择范围**:常规范围 `config` / `rules` / `architecture` / `instructions`;分支恢复单独显式声明来源分支。
|
|
25
|
+
2. **展示预览**:来源版本、提交、缺失文件与冲突;默认只读预览,未经确认不写入本地。
|
|
26
|
+
3. **冲突决策**:本地有修改时逐项展示差异与决策(`keep-local` / `accept-remote` / `skip`);不得因关闭扫描直接覆盖本地有意修改。删除恢复只允许 `accept-remote` 并绑定 preview hash 与来源。
|
|
27
|
+
4. **报告结果**:应用、跳过、冲突遗留分列;冲突未决项保持本地原样。
|
|
28
|
+
|
|
29
|
+
## 命令
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
npx hunter-harness harness-pull --scope config,rules --json
|
|
33
|
+
npx hunter-harness harness-pull --scope branch_files --branch main --json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 关键规则
|
|
37
|
+
|
|
38
|
+
| 规则 | 要点 |
|
|
39
|
+
|------|------|
|
|
40
|
+
| 只读默认 | 未确认的预览不得写本地;`--dry-run` 不产生任何写入 |
|
|
41
|
+
| 本地修改保护 | 有本地修改时必须显示差异与决策,不静默覆盖 |
|
|
42
|
+
| 删除恢复 | 只接受 `accept-remote`,并绑定 preview hash、artifact、version 与来源分支 |
|
|
43
|
+
| 归档边界 | 归档不属于常规下拉;需要历史归档时提示用户走 Platform 变更记录下载 |
|
|
44
|
+
|
|
45
|
+
## P0 执行可信度规则
|
|
46
|
+
|
|
47
|
+
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
48
|
+
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
49
|
+
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
50
|
+
|
|
51
|
+
## 生成内容语言约定
|
|
52
|
+
|
|
53
|
+
- sync/ingest 等生成的文档、规则、知识条目、架构说明一律**优先使用中文**撰写(标识符、命令、代码、API 字段名保持原文)
|
|
54
|
+
- 面向平台展示的标题/摘要/正文默认中文;仅当用户明确要求或目标系统强制时才用英文
|
|
55
|
+
> 片段:p0-trust
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-push
|
|
3
|
+
description: 上传本地配置/规则/架构/指令(及显式归档)到 Hunter Platform。仅当用户显式调用 /harness-push
|
|
4
|
+
或明确说'上传到平台'时使用;不得因存在本地修改就自动触发。
|
|
5
|
+
---
|
|
6
|
+
<!-- generated by harness_deploy.py; core=99e00f374c938811; overlay=java; agent=codex; do not edit -->
|
|
7
|
+
# harness-push — 上传到 Hunter Platform
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
把本地受管内容(配置、规则、架构、指令,及显式选择的归档包)上传到 Hunter Platform。本 skill 只负责理解意图、展示预览和收集确认;三方 diff、敏感扫描、幂等与本地事务由 CLI/core 完成,不得绕过命令手工拼接上传。
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
仅当用户显式调用 `/harness-push`(或明确说"上传到 Hunter Platform")时执行。用户只是修改了配置/规则/指令时,**不得**自动建议上传。
|
|
16
|
+
|
|
17
|
+
## 前置条件
|
|
18
|
+
|
|
19
|
+
- 远端同步已配置:`HUNTER_REMOTE_SYNC_URL`、`HUNTER_REMOTE_SYNC_TOKEN`、`HUNTER_REMOTE_SYNC_ACTOR_ID`。缺失时 CLI 固定 fail closed(`PUSH_PULL_CLI_UNAVAILABLE`),**不得**改用旧 HTTP fallback 或手工 API 调用。
|
|
20
|
+
- 归档上传只选择已写入 outbox 的确定性包(阶段 06 产物);不存在可复用包时提示先完成本地归档,**不得**在 Push 内隐式补做 finalize/重建 ZIP。
|
|
21
|
+
|
|
22
|
+
## 交互流程
|
|
23
|
+
|
|
24
|
+
1. **选择范围**:`config` / `rules` / `architecture` / `instructions` / `all`,或显式归档 `--scope archive --change <change-key>`。归档必须显式,避免误传历史包或无法确定目标 Change。
|
|
25
|
+
2. **展示预览**:分支、提交、远端基线和实际变化文件;无变化时直接结束,不创建空版本。
|
|
26
|
+
3. **用户确认**:可覆盖风险(hard 敏感阻断除外)必须显式确认后才上传;确认只对本次 preview 有效。
|
|
27
|
+
4. **按内容分类报告**:成功、跳过、冲突和可重试项分开列出;冲突只投影机器决策,可附 `--resolve <path=keep-local|accept-remote|skip>` 逐项选择。
|
|
28
|
+
|
|
29
|
+
## 命令
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
npx hunter-harness harness-push --scope config,rules --json
|
|
33
|
+
npx hunter-harness harness-push --scope archive --change <change-key> --json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 关键规则
|
|
37
|
+
|
|
38
|
+
| 规则 | 要点 |
|
|
39
|
+
|------|------|
|
|
40
|
+
| 无变化不上传 | 预览无变化时返回 `no_changes`,不创建确认、不调用执行入口 |
|
|
41
|
+
| 敏感与凭据 | 不做内容遮盖;路径白名单、凭据文件排除、哈希校验保持启用;hard 敏感阻断不得生成确认 |
|
|
42
|
+
| 归档边界 | 归档不进普通范围;`--scope archive` 必须带 `--change`;只消费已有 outbox claim |
|
|
43
|
+
| 失败语义 | `PUSH_PULL_RECEIPT_INVALID`/远端未确认 = 未上传,不得宣称成功;可重试项标注后交还用户 |
|
|
44
|
+
|
|
45
|
+
## P0 执行可信度规则
|
|
46
|
+
|
|
47
|
+
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
48
|
+
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
49
|
+
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
50
|
+
|
|
51
|
+
## 生成内容语言约定
|
|
52
|
+
|
|
53
|
+
- sync/ingest 等生成的文档、规则、知识条目、架构说明一律**优先使用中文**撰写(标识符、命令、代码、API 字段名保持原文)
|
|
54
|
+
- 面向平台展示的标题/摘要/正文默认中文;仅当用户明确要求或目标系统强制时才用英文
|
|
55
|
+
> 片段:p0-trust
|
|
@@ -4,7 +4,7 @@ description: 6维度代码审查(架构/安全/规范/兼容/测试/性能)
|
|
|
4
4
|
.harness/context-index.json)和测试场景表,在隔离上下文运行。仅当用户显式调用 /harness-review 时使用;不得在
|
|
5
5
|
test 结束后自动接续执行。
|
|
6
6
|
---
|
|
7
|
-
<!-- generated by harness_deploy.py; core=
|
|
7
|
+
<!-- generated by harness_deploy.py; core=99e00f374c938811; overlay=java; agent=codex; do not edit -->
|
|
8
8
|
# harness-review — 代码审查
|
|
9
9
|
|
|
10
10
|
## Purpose
|
|
@@ -3,7 +3,7 @@ name: harness-run
|
|
|
3
3
|
description: 按变更簇执行 TDD 编码循环(RED→GREEN→REFACTOR→编译验证),逐变更簇实现计划中的任务。仅当用户显式调用
|
|
4
4
|
/harness-run 时使用;不得因用户提到编码/实现就自动触发,也不得被其他阶段 skill 自动接续。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=99e00f374c938811; overlay=java; agent=codex; do not edit -->
|
|
7
7
|
# harness-run — 需求编码
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -3,7 +3,7 @@ name: harness-submit
|
|
|
3
3
|
description: 最终提交封装:验证→中文 commit→提交/推送;worktree 模式含 --no-ff 合并回主分支。仅当用户显式调用
|
|
4
4
|
/harness-submit(或 /harness-merge 重入合并段)时使用;用户口头说'提交/commit/push'时必须先确认,不得自动触发。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=99e00f374c938811; overlay=java; agent=codex; do not edit -->
|
|
7
7
|
# harness-submit — 最终提交(含 worktree 合并)
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -4,7 +4,7 @@ description: Use when the user asks to synchronize, refresh, or validate Harness
|
|
|
4
4
|
metadata, adapters, remote knowledge ownership, instruction entrypoints,
|
|
5
5
|
config origins, or CodeGraph status.
|
|
6
6
|
---
|
|
7
|
-
<!-- generated by harness_deploy.py; core=
|
|
7
|
+
<!-- generated by harness_deploy.py; core=99e00f374c938811; overlay=java; agent=codex; do not edit -->
|
|
8
8
|
# harness-sync
|
|
9
9
|
|
|
10
10
|
## Purpose
|
|
@@ -3,7 +3,7 @@ name: harness-test
|
|
|
3
3
|
description: 测试执行:读取场景表,执行单元测试+API接口测试+数据兼容验证,输出测试报告。仅当用户显式调用 /harness-test
|
|
4
4
|
时使用;不得在 run 结束后自动接续执行。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=99e00f374c938811; overlay=java; agent=codex; do not edit -->
|
|
7
7
|
# harness-test — 测试执行
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -796,6 +796,121 @@ def _receipt_artifact_targets(
|
|
|
796
796
|
return targets, None
|
|
797
797
|
|
|
798
798
|
|
|
799
|
+
def _verify_plan_v2(change_dir: Path) -> dict[str, Any] | None:
|
|
800
|
+
"""v2 finalizer(TS)证据的只读验收。
|
|
801
|
+
|
|
802
|
+
v2 不产生 meta/plan-finalization.json;canonical 证据是
|
|
803
|
+
meta/plan-finalization-transactions/ + meta/publication-journals/。
|
|
804
|
+
本路径只做结构验收:最新事务终态、匹配 journal 的 committed/readback、
|
|
805
|
+
durable targets 存在且字节哈希与 binding 一致。内容质量由 TS 质量层裁决,
|
|
806
|
+
Python 不重复审判。无 v2 证据时返回 None(调用方回退 RECEIPT_MISSING)。
|
|
807
|
+
"""
|
|
808
|
+
transactions_dir = change_dir / "meta" / "plan-finalization-transactions"
|
|
809
|
+
if not transactions_dir.is_dir():
|
|
810
|
+
return None
|
|
811
|
+
transactions = sorted(
|
|
812
|
+
transactions_dir.glob("*.json"),
|
|
813
|
+
key=lambda path: path.stat().st_mtime,
|
|
814
|
+
)
|
|
815
|
+
if not transactions:
|
|
816
|
+
return None
|
|
817
|
+
latest: dict[str, Any] | None = None
|
|
818
|
+
for candidate in reversed(transactions):
|
|
819
|
+
try:
|
|
820
|
+
payload = json.loads(candidate.read_text(encoding="utf-8-sig"))
|
|
821
|
+
except (OSError, json.JSONDecodeError):
|
|
822
|
+
continue
|
|
823
|
+
if isinstance(payload, dict):
|
|
824
|
+
latest = payload
|
|
825
|
+
break
|
|
826
|
+
if latest is None:
|
|
827
|
+
return None
|
|
828
|
+
if latest.get("change_key") != change_dir.name:
|
|
829
|
+
return _result_error(
|
|
830
|
+
"RECEIPT_CHANGE_NAME_INVALID",
|
|
831
|
+
"v2 transaction change_key does not match the change directory",
|
|
832
|
+
)
|
|
833
|
+
if latest.get("status") != "publication_committed_event_complete":
|
|
834
|
+
return _result_error(
|
|
835
|
+
"RECEIPT_NOT_FINALIZED",
|
|
836
|
+
f"v2 transaction status is {latest.get('status')!r}, "
|
|
837
|
+
"expected 'publication_committed_event_complete'",
|
|
838
|
+
)
|
|
839
|
+
operation_id = str(latest.get("operation_id") or "")
|
|
840
|
+
journals_dir = change_dir / "meta" / "publication-journals"
|
|
841
|
+
journal: dict[str, Any] | None = None
|
|
842
|
+
if journals_dir.is_dir():
|
|
843
|
+
for candidate in sorted(journals_dir.glob("*.json")):
|
|
844
|
+
try:
|
|
845
|
+
payload = json.loads(candidate.read_text(encoding="utf-8-sig"))
|
|
846
|
+
except (OSError, json.JSONDecodeError):
|
|
847
|
+
continue
|
|
848
|
+
if isinstance(payload, dict) and payload.get("operation_id") == operation_id:
|
|
849
|
+
journal = payload
|
|
850
|
+
break
|
|
851
|
+
if journal is None:
|
|
852
|
+
return _result_error(
|
|
853
|
+
"PUBLICATION_JOURNAL_MISSING",
|
|
854
|
+
f"no publication journal matches v2 operation {operation_id!r}",
|
|
855
|
+
)
|
|
856
|
+
if journal.get("state") != "committed" or journal.get("readback") != "verified":
|
|
857
|
+
return _result_error(
|
|
858
|
+
"PUBLICATION_JOURNAL_NOT_COMMITTED",
|
|
859
|
+
"v2 publication journal is not committed with verified readback",
|
|
860
|
+
)
|
|
861
|
+
binding = journal.get("binding")
|
|
862
|
+
if not isinstance(binding, dict):
|
|
863
|
+
return _result_error("PUBLICATION_BINDING_INVALID", "v2 journal binding missing")
|
|
864
|
+
payload_hashes = binding.get("expected_payload_hashes")
|
|
865
|
+
ownership_paths = binding.get("ownership_paths")
|
|
866
|
+
if not isinstance(payload_hashes, dict) or not isinstance(ownership_paths, list):
|
|
867
|
+
return _result_error("PUBLICATION_BINDING_INVALID", "v2 binding fields malformed")
|
|
868
|
+
required = {
|
|
869
|
+
f"plans/{change_dir.name}-design.md",
|
|
870
|
+
f"plans/{change_dir.name}-plan.md",
|
|
871
|
+
f"plans/{change_dir.name}-implementation-detail.md",
|
|
872
|
+
f"plans/{change_dir.name}-test-scenarios.md",
|
|
873
|
+
"meta/gate-policy.json",
|
|
874
|
+
"meta/worktree.json",
|
|
875
|
+
}
|
|
876
|
+
missing_required = sorted(required - set(ownership_paths))
|
|
877
|
+
if missing_required:
|
|
878
|
+
return _result_error(
|
|
879
|
+
"RECEIPT_FILES_INCOMPLETE",
|
|
880
|
+
"v2 journal omits required artifacts: " + ", ".join(missing_required),
|
|
881
|
+
)
|
|
882
|
+
for rel, expected_hash in payload_hashes.items():
|
|
883
|
+
if not isinstance(expected_hash, str) or not expected_hash.startswith("sha256:"):
|
|
884
|
+
return _result_error("PUBLICATION_BINDING_INVALID", f"{rel}: malformed hash")
|
|
885
|
+
target = change_dir / rel
|
|
886
|
+
try:
|
|
887
|
+
resolved = target.resolve()
|
|
888
|
+
resolved.relative_to(change_dir.resolve())
|
|
889
|
+
except (OSError, ValueError):
|
|
890
|
+
return _result_error(
|
|
891
|
+
"RECEIPT_FILE_PATH_INVALID",
|
|
892
|
+
f"v2 artifact path resolves outside the change directory: {rel}",
|
|
893
|
+
)
|
|
894
|
+
if not target.is_file():
|
|
895
|
+
return _result_error("ARTIFACT_MISSING", f"published artifact missing: {rel}")
|
|
896
|
+
actual_hash = "sha256:" + hashlib.sha256(target.read_bytes()).hexdigest()
|
|
897
|
+
if actual_hash != expected_hash:
|
|
898
|
+
return _result_error(
|
|
899
|
+
"ARTIFACT_HASH_DRIFT",
|
|
900
|
+
f"{rel}: content hash {actual_hash} != v2 binding {expected_hash}",
|
|
901
|
+
)
|
|
902
|
+
return {
|
|
903
|
+
"ok": True,
|
|
904
|
+
"code": "PLAN_V2_VERIFIED",
|
|
905
|
+
"v2": True,
|
|
906
|
+
"operationId": operation_id,
|
|
907
|
+
"runId": latest.get("run_id"),
|
|
908
|
+
"attempt": latest.get("attempt"),
|
|
909
|
+
"artifactCount": len(payload_hashes),
|
|
910
|
+
"status": latest.get("status"),
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
|
|
799
914
|
def verify_plan(change_dir: Path) -> dict[str, Any]:
|
|
800
915
|
"""Read-only verification of a finalized plan (retro §5.8).
|
|
801
916
|
|
|
@@ -807,6 +922,10 @@ def verify_plan(change_dir: Path) -> dict[str, Any]:
|
|
|
807
922
|
change_dir = change_dir.resolve()
|
|
808
923
|
receipt_path = change_dir / "meta" / "plan-finalization.json"
|
|
809
924
|
if not receipt_path.is_file():
|
|
925
|
+
# v2 finalizer 证据路径(canonical 事实源是 transactions + journals)
|
|
926
|
+
v2_result = _verify_plan_v2(change_dir)
|
|
927
|
+
if v2_result is not None:
|
|
928
|
+
return v2_result
|
|
810
929
|
return _result_error("RECEIPT_MISSING", f"receipt not found: {receipt_path}")
|
|
811
930
|
|
|
812
931
|
try:
|