@hunter-harness/workflow-harness 0.2.80 → 0.2.81
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/harness-archive/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/harness-plan/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-review/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +13 -3
- package/harness/bundles/general/claude-code/scripts/harness_context.py +77 -3
- package/harness/bundles/general/claude-code/scripts/harness_events.py +35 -2
- package/harness/bundles/general/claude-code/scripts/harness_plan_finalize.py +6 -1
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-review/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +13 -3
- package/harness/bundles/general/codebuddy/scripts/harness_context.py +77 -3
- package/harness/bundles/general/codebuddy/scripts/harness_events.py +35 -2
- package/harness/bundles/general/codebuddy/scripts/harness_plan_finalize.py +6 -1
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/harness-archive/SKILL.md +13 -3
- package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +13 -3
- package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +13 -3
- package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +13 -3
- package/harness/bundles/general/codex/harness-plan/SKILL.md +13 -3
- package/harness/bundles/general/codex/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-review/SKILL.md +13 -3
- package/harness/bundles/general/codex/harness-run/SKILL.md +13 -3
- package/harness/bundles/general/codex/harness-submit/SKILL.md +13 -3
- package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-test/SKILL.md +13 -3
- package/harness/bundles/general/codex/scripts/harness_context.py +77 -3
- package/harness/bundles/general/codex/scripts/harness_events.py +35 -2
- package/harness/bundles/general/codex/scripts/harness_plan_finalize.py +6 -1
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +13 -3
- package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +13 -3
- package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +13 -3
- package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +13 -3
- package/harness/bundles/general/cursor/harness-plan/SKILL.md +13 -3
- package/harness/bundles/general/cursor/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-review/SKILL.md +13 -3
- package/harness/bundles/general/cursor/harness-run/SKILL.md +13 -3
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +13 -3
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-test/SKILL.md +13 -3
- package/harness/bundles/general/cursor/scripts/harness_context.py +77 -3
- package/harness/bundles/general/cursor/scripts/harness_events.py +35 -2
- package/harness/bundles/general/cursor/scripts/harness_plan_finalize.py +6 -1
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-archive/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-package/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-plan/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-review/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-submit/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +13 -3
- package/harness/bundles/java/claude-code/scripts/harness_context.py +77 -3
- package/harness/bundles/java/claude-code/scripts/harness_events.py +35 -2
- package/harness/bundles/java/claude-code/scripts/harness_plan_finalize.py +6 -1
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-package/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-review/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +13 -3
- package/harness/bundles/java/codebuddy/scripts/harness_context.py +77 -3
- package/harness/bundles/java/codebuddy/scripts/harness_events.py +35 -2
- package/harness/bundles/java/codebuddy/scripts/harness_plan_finalize.py +6 -1
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/harness-apidoc/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-archive/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-package/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-plan/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-review/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-run/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-submit/SKILL.md +13 -3
- package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-test/SKILL.md +13 -3
- package/harness/bundles/java/codex/scripts/harness_context.py +77 -3
- package/harness/bundles/java/codex/scripts/harness_events.py +35 -2
- package/harness/bundles/java/codex/scripts/harness_plan_finalize.py +6 -1
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-archive/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-package/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-plan/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-review/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-run/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-submit/SKILL.md +13 -3
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-test/SKILL.md +13 -3
- package/harness/bundles/java/cursor/scripts/harness_context.py +77 -3
- package/harness/bundles/java/cursor/scripts/harness_events.py +35 -2
- package/harness/bundles/java/cursor/scripts/harness_plan_finalize.py +6 -1
- package/harness/manifests/general/claude-code.json +17 -17
- package/harness/manifests/general/codebuddy.json +17 -17
- package/harness/manifests/general/codex.json +17 -17
- package/harness/manifests/general/cursor.json +17 -17
- package/harness/manifests/java/claude-code.json +19 -19
- package/harness/manifests/java/codebuddy.json +19 -19
- package/harness/manifests/java/codex.json +19 -19
- package/harness/manifests/java/cursor.json +19 -19
- package/hunter-workflow-family.json +3 -3
- package/package.json +1 -1
|
@@ -1904,6 +1904,7 @@ def cmd_append(args: argparse.Namespace) -> int:
|
|
|
1904
1904
|
file=sys.stderr,
|
|
1905
1905
|
)
|
|
1906
1906
|
phase_closed = False
|
|
1907
|
+
phase_start_duplicate = False
|
|
1907
1908
|
projection_error: str | None = None
|
|
1908
1909
|
attempt_error: str | None = None
|
|
1909
1910
|
auto_sealed_events: list[dict[str, Any]] = []
|
|
@@ -1951,10 +1952,25 @@ def cmd_append(args: argparse.Namespace) -> int:
|
|
|
1951
1952
|
except ValueError as exc:
|
|
1952
1953
|
projection_error = str(exc)
|
|
1953
1954
|
elif args.type == "phase.start":
|
|
1955
|
+
# Re-appending the same (phase, run_id) is the caller restating a
|
|
1956
|
+
# start that already exists — `gate begin` writes one, and the
|
|
1957
|
+
# logging protocol used to ask for a second. Treat it as a no-op
|
|
1958
|
+
# rather than a duplicate; two identical phase.start events make
|
|
1959
|
+
# `plan finalize` unrecoverable via PHASE_START_DUPLICATE.
|
|
1960
|
+
if run_id is not None and any(
|
|
1961
|
+
item.get("phase") == args.phase
|
|
1962
|
+
and item.get("type") == "phase.start"
|
|
1963
|
+
and item.get("run_id") == run_id
|
|
1964
|
+
for item in existing_events
|
|
1965
|
+
):
|
|
1966
|
+
phase_start_duplicate = True
|
|
1954
1967
|
# HH-WF-20260730-001: a new phase.start must not be appended
|
|
1955
1968
|
# while a prior attempt for the same phase is still open —
|
|
1956
1969
|
# auto-seal it first so timing never has two open attempts.
|
|
1957
|
-
open_attempts =
|
|
1970
|
+
open_attempts = (
|
|
1971
|
+
[] if phase_start_duplicate
|
|
1972
|
+
else open_attempts_for_phase(existing_events, args.phase)
|
|
1973
|
+
)
|
|
1958
1974
|
if open_attempts:
|
|
1959
1975
|
inferred_reason = infer_auto_seal_reason(
|
|
1960
1976
|
open_attempts[-1].get("events") or []
|
|
@@ -1964,7 +1980,12 @@ def cmd_append(args: argparse.Namespace) -> int:
|
|
|
1964
1980
|
phase=args.phase,
|
|
1965
1981
|
seal_reason=inferred_reason,
|
|
1966
1982
|
)
|
|
1967
|
-
if
|
|
1983
|
+
if (
|
|
1984
|
+
not phase_closed
|
|
1985
|
+
and not phase_start_duplicate
|
|
1986
|
+
and projection_error is None
|
|
1987
|
+
and attempt_error is None
|
|
1988
|
+
):
|
|
1968
1989
|
for seal_event in auto_sealed_events:
|
|
1969
1990
|
atomic_append_line(
|
|
1970
1991
|
path,
|
|
@@ -1976,6 +1997,18 @@ def cmd_append(args: argparse.Namespace) -> int:
|
|
|
1976
1997
|
)
|
|
1977
1998
|
except (OSError, TimeoutError, ValueError) as exc:
|
|
1978
1999
|
return emit_error(f"append failed: {exc}", as_json=as_json)
|
|
2000
|
+
if phase_start_duplicate:
|
|
2001
|
+
if as_json:
|
|
2002
|
+
print(json.dumps({
|
|
2003
|
+
"ok": True,
|
|
2004
|
+
"skipped": True,
|
|
2005
|
+
"reason": "phase-start-already-recorded",
|
|
2006
|
+
"phase": args.phase,
|
|
2007
|
+
"run_id": event.get("run_id"),
|
|
2008
|
+
}, ensure_ascii=False))
|
|
2009
|
+
else:
|
|
2010
|
+
print("ok (phase.start already recorded for this run id)")
|
|
2011
|
+
return 0
|
|
1979
2012
|
if phase_closed:
|
|
1980
2013
|
return emit_error(
|
|
1981
2014
|
"PHASE_ALREADY_CLOSED: refusing a second phase.end for the same "
|
|
@@ -735,7 +735,12 @@ def _validate_plan_start(
|
|
|
735
735
|
if len(matching) > 1:
|
|
736
736
|
return _result_error(
|
|
737
737
|
"PHASE_START_DUPLICATE",
|
|
738
|
-
f"found {len(matching)} matching plan phase.start events"
|
|
738
|
+
f"found {len(matching)} matching plan phase.start events for run id "
|
|
739
|
+
f"{run_id}. `harness_gate.py begin` already appends phase.start; a "
|
|
740
|
+
"second manual append of the same run id creates this state. Recover "
|
|
741
|
+
"with a fresh run id and the next attempt number (attempts are global "
|
|
742
|
+
"per phase, not per run id): append phase.start with both, then "
|
|
743
|
+
"finalize with the same pair.",
|
|
739
744
|
)
|
|
740
745
|
return {"ok": True, "phaseStartCount": 1}
|
|
741
746
|
|
|
@@ -3,7 +3,7 @@ name: harness-apidoc
|
|
|
3
3
|
description: 从 Java 后端代码生成结构化前端 API 文档(Controller/VO/ErrorCode)。仅当用户显式调用
|
|
4
4
|
/harness-apidoc 时使用,不得自动触发。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-apidoc — 前端接口文档(Java overlay)
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -75,13 +75,23 @@ description: 从 Java 后端代码生成结构化前端 API 文档(Controller/
|
|
|
75
75
|
|
|
76
76
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
77
77
|
|
|
78
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
79
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
80
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
81
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
82
|
+
|
|
78
83
|
```powershell
|
|
79
|
-
|
|
84
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
85
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
86
|
+
# 阶段中的其他事件才用 append
|
|
87
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
80
88
|
```
|
|
81
89
|
|
|
82
90
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
83
91
|
|
|
84
92
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
85
93
|
|
|
86
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
94
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
95
|
+
|
|
96
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
87
97
|
> 片段:logging · phase=`apidoc`
|
|
@@ -3,7 +3,7 @@ name: harness-archive
|
|
|
3
3
|
description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档)到 .harness/archive/,含归档元数据。仅当用户显式调用
|
|
4
4
|
/harness-archive 时使用;不得被其他阶段 skill 自动接续触发。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-archive — 变更归档
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -258,13 +258,23 @@ git 命令通过 `powershell.exe -Command "..."` 执行;archive-meta.md 和 su
|
|
|
258
258
|
|
|
259
259
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
260
260
|
|
|
261
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
262
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
263
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
264
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
265
|
+
|
|
261
266
|
```powershell
|
|
262
|
-
|
|
267
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
268
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
269
|
+
# 阶段中的其他事件才用 append
|
|
270
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
263
271
|
```
|
|
264
272
|
|
|
265
273
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
266
274
|
|
|
267
275
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
268
276
|
|
|
269
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
277
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
278
|
+
|
|
279
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
270
280
|
> 片段:logging · phase=`archive`
|
|
@@ -3,7 +3,7 @@ name: harness-codebase-map
|
|
|
3
3
|
description: 分析现有代码库并生成 .harness/codebase/map/
|
|
4
4
|
下的结构化代码库地图。用于陌生项目理解、重大改造前梳理、harness-sync 提示 map 过期后的人工刷新。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-codebase-map — 代码库地图
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -94,13 +94,23 @@ description: 分析现有代码库并生成 .harness/codebase/map/
|
|
|
94
94
|
|
|
95
95
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
96
96
|
|
|
97
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
98
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
99
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
100
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
101
|
+
|
|
97
102
|
```powershell
|
|
98
|
-
|
|
103
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
104
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
105
|
+
# 阶段中的其他事件才用 append
|
|
106
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
99
107
|
```
|
|
100
108
|
|
|
101
109
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
102
110
|
|
|
103
111
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
104
112
|
|
|
105
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
113
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
114
|
+
|
|
115
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
106
116
|
> 片段:logging · phase=`codebase-map`;默认写 reports,有未归档变更时另写 change events
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: harness-knowledge-ingest
|
|
3
3
|
description: 确认归档 ZIP 已上传并由 Hunter Platform 在服务端解包、校验和入库。客户端不再构建或维护本地知识索引。
|
|
4
4
|
---
|
|
5
|
-
<!-- generated by harness_deploy.py; core=
|
|
5
|
+
<!-- generated by harness_deploy.py; core=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
6
6
|
# harness-knowledge-ingest
|
|
7
7
|
|
|
8
8
|
知识 ingest 完全由 Hunter Platform 负责。归档完成时,客户端生成一个确定性 ZIP;
|
|
@@ -81,13 +81,23 @@ ZIP 已按收据策略清理,且平台下载接口可以恢复原包。
|
|
|
81
81
|
|
|
82
82
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
83
83
|
|
|
84
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
85
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
86
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
87
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
88
|
+
|
|
84
89
|
```powershell
|
|
85
|
-
|
|
90
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
91
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
92
|
+
# 阶段中的其他事件才用 append
|
|
93
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
86
94
|
```
|
|
87
95
|
|
|
88
96
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
89
97
|
|
|
90
98
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
91
99
|
|
|
92
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
100
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
101
|
+
|
|
102
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
93
103
|
> 片段:logging · phase=`knowledge-ingest` · 记录 package hash、服务端状态与失败重试路径
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: harness-knowledge-query
|
|
3
3
|
description: 在规划、实现或排查前,通过 hunter-harness CLI 查询远端项目知识库。远端不可用时直接报告不可用,不建立本地索引或离线回退。
|
|
4
4
|
---
|
|
5
|
-
<!-- generated by harness_deploy.py; core=
|
|
5
|
+
<!-- generated by harness_deploy.py; core=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
6
6
|
# harness-knowledge-query
|
|
7
7
|
|
|
8
8
|
项目知识以 Hunter Platform 的服务端索引为唯一真源。客户端只提交查询并消费结果:
|
|
@@ -75,13 +75,23 @@ powershell.exe -Command "npx hunter-harness knowledge query '<用户需求原文
|
|
|
75
75
|
|
|
76
76
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
77
77
|
|
|
78
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
79
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
80
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
81
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
82
|
+
|
|
78
83
|
```powershell
|
|
79
|
-
|
|
84
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
85
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
86
|
+
# 阶段中的其他事件才用 append
|
|
87
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
80
88
|
```
|
|
81
89
|
|
|
82
90
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
83
91
|
|
|
84
92
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
85
93
|
|
|
86
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
94
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
95
|
+
|
|
96
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
87
97
|
> 片段:logging · phase=`knowledge-query` · 成功记录命中摘要,失败记录远端错误码且不做本地回退
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: harness-package
|
|
3
3
|
description: 增量模块打包:拉取最新→编译验证→mvn package→汇总 jar/war。仅当用户显式调用 /harness-package 时使用,不得自动触发。
|
|
4
4
|
---
|
|
5
|
-
<!-- generated by harness_deploy.py; core=
|
|
5
|
+
<!-- generated by harness_deploy.py; core=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
6
6
|
# harness-package — 增量模块打包(Java overlay)
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
@@ -72,13 +72,23 @@ description: 增量模块打包:拉取最新→编译验证→mvn package→
|
|
|
72
72
|
|
|
73
73
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
74
74
|
|
|
75
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
76
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
77
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
78
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
79
|
+
|
|
75
80
|
```powershell
|
|
76
|
-
|
|
81
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
82
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
83
|
+
# 阶段中的其他事件才用 append
|
|
84
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
77
85
|
```
|
|
78
86
|
|
|
79
87
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
80
88
|
|
|
81
89
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
82
90
|
|
|
83
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
91
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
92
|
+
|
|
93
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
84
94
|
> 片段:logging · phase=`package`
|
|
@@ -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=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-plan — 需求规划
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -135,13 +135,23 @@ change-name 范围变更 → 提示重命名或记 🟡WARN(→ `reference.md`
|
|
|
135
135
|
|
|
136
136
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
137
137
|
|
|
138
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
139
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
140
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
141
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
142
|
+
|
|
138
143
|
```powershell
|
|
139
|
-
|
|
144
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
145
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
146
|
+
# 阶段中的其他事件才用 append
|
|
147
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
140
148
|
```
|
|
141
149
|
|
|
142
150
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
143
151
|
|
|
144
152
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
145
153
|
|
|
146
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
154
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
155
|
+
|
|
156
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
147
157
|
> 片段:logging · phase=`plan`
|
|
@@ -3,7 +3,7 @@ name: harness-pull
|
|
|
3
3
|
description: 从 Hunter Platform 下拉配置/规则/架构/指令(及显式来源分支的分支文件恢复)。仅当用户显式调用
|
|
4
4
|
/harness-pull 或明确说'从平台拉取/恢复'时使用;不得自动触发。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-pull — 从 Hunter Platform 下拉与恢复
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -3,7 +3,7 @@ name: harness-push
|
|
|
3
3
|
description: 上传本地配置/规则/架构/指令(及显式归档)到 Hunter Platform。仅当用户显式调用 /harness-push
|
|
4
4
|
或明确说'上传到平台'时使用;不得因存在本地修改就自动触发。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-push — 上传到 Hunter Platform
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -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=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
8
8
|
# harness-review — 代码审查
|
|
9
9
|
|
|
10
10
|
## Purpose
|
|
@@ -153,13 +153,23 @@ review 读取 `state-snapshot.json`(`harness_state.py` / state-layout-protocol
|
|
|
153
153
|
|
|
154
154
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
155
155
|
|
|
156
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
157
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
158
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
159
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
160
|
+
|
|
156
161
|
```powershell
|
|
157
|
-
|
|
162
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
163
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
164
|
+
# 阶段中的其他事件才用 append
|
|
165
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
158
166
|
```
|
|
159
167
|
|
|
160
168
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
161
169
|
|
|
162
170
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
163
171
|
|
|
164
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
172
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
173
|
+
|
|
174
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
165
175
|
> 片段:logging · phase=`review` · 事件:phase/decision/verification/issue/artifact
|
|
@@ -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=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-run — 需求编码
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -156,13 +156,23 @@ python <skills-root>/scripts/harness_test_guard.py record --project . --change-d
|
|
|
156
156
|
|
|
157
157
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
158
158
|
|
|
159
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
160
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
161
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
162
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
163
|
+
|
|
159
164
|
```powershell
|
|
160
|
-
|
|
165
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
166
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
167
|
+
# 阶段中的其他事件才用 append
|
|
168
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
161
169
|
```
|
|
162
170
|
|
|
163
171
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
164
172
|
|
|
165
173
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
166
174
|
|
|
167
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
175
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
176
|
+
|
|
177
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
168
178
|
> 片段:logging · phase=`run`
|
|
@@ -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=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-submit — 最终提交(含 worktree 合并)
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -167,13 +167,23 @@ git 经 PowerShell;commit/报告不得含明文密钥。遵循 `../protocols/s
|
|
|
167
167
|
|
|
168
168
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
169
169
|
|
|
170
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
171
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
172
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
173
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
174
|
+
|
|
170
175
|
```powershell
|
|
171
|
-
|
|
176
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
177
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
178
|
+
# 阶段中的其他事件才用 append
|
|
179
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
172
180
|
```
|
|
173
181
|
|
|
174
182
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
175
183
|
|
|
176
184
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
177
185
|
|
|
178
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
186
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
187
|
+
|
|
188
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
179
189
|
> 片段:logging · phase=`submit`/`merge`
|
|
@@ -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=d3464399d5abb78b; overlay=java; agent=codebuddy; 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=d3464399d5abb78b; overlay=java; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-test — 测试执行
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -233,13 +233,23 @@ python <skills-root>/scripts/harness_test_guard.py record --project . --change-d
|
|
|
233
233
|
|
|
234
234
|
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
235
235
|
|
|
236
|
+
**`phase.start` 由 `harness_gate.py begin` 写,不要再手工追加一次。** 两条同 `run-id` 的
|
|
237
|
+
`phase.start` 会让 `plan finalize` 以 `PHASE_START_DUPLICATE` 卡死,而且手工那次会先触发
|
|
238
|
+
auto-seal、把正在开始的 attempt 封成 `RECOVERED`。要补触发指令说明就带 `--note` 跑 `gate begin`。
|
|
239
|
+
(重复追加现已按 `(phase, run-id)` 判为幂等 no-op,但依赖它不如不写。)
|
|
240
|
+
|
|
236
241
|
```powershell
|
|
237
|
-
|
|
242
|
+
# 阶段开始:gate begin 负责,note 在这里给
|
|
243
|
+
python <skills-root>/scripts/harness_gate.py begin --change-dir ".harness/changes/<change-name>" --phase <phase> --note "<触发指令>"
|
|
244
|
+
# 阶段中的其他事件才用 append
|
|
245
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type <command|issue|verification> --run-id <phase-run-id> --note "<摘要>"
|
|
238
246
|
```
|
|
239
247
|
|
|
240
248
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
241
249
|
|
|
242
250
|
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
243
251
|
|
|
244
|
-
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n
|
|
252
|
+
每个阶段的 `phase.start` 与对应 `phase.end` 必须复用同一 `--run-id` / `--attempt`;阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`。重试同一阶段时生成新的 run-id 并增加 `--attempt <n>`,不得覆盖或伪装成一次执行。**`attempt` 按 phase 全局递增,不是按 run-id**:一个 run-id 只绑定一个 attempt,重试必须「新 run-id + 下一个 attempt」两者同时换,只换其一会撞 `EVENT_ATTEMPT_CONFLICT` 或 `PHASE_ALREADY_CLOSED`。已发布的 plan 用 `harness_plan_finalize.py republish` 自动分配两者。
|
|
253
|
+
|
|
254
|
+
阶段跑得久(plan/run 常见)时用 `harness_context.py renew --project . --change <cn> --executor <tool>` 续租;租约到期本身不再阻断 `close`(同一 owner 的过期租约不构成冲突,收据里记 `leaseLapsed`),但续租能让 `view` 的状态如实反映在跑。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
245
255
|
> 片段:logging · phase=`test` · 事件:phase/command/verification/decision/issue/artifact
|