@hunter-harness/workflow-harness 0.2.85 → 0.2.86
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 +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 +3 -2
- package/harness/bundles/general/claude-code/harness-plan/checklist.md +18 -79
- package/harness/bundles/general/claude-code/harness-plan/protocols.md +3 -1
- package/harness/bundles/general/claude-code/harness-plan/reference.md +37 -8
- 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 +1 -1
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +6 -4
- 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_change.py +25 -7
- package/harness/bundles/general/claude-code/scripts/harness_context.py +62 -19
- package/harness/bundles/general/claude-code/scripts/harness_fixback.py +4 -0
- package/harness/bundles/general/claude-code/scripts/harness_gate.py +208 -72
- package/harness/bundles/general/claude-code/scripts/harness_ledger.py +43 -0
- package/harness/bundles/general/claude-code/scripts/harness_paths.py +60 -0
- package/harness/bundles/general/claude-code/scripts/harness_phase.py +24 -6
- package/harness/bundles/general/claude-code/scripts/harness_plan_finalize.py +124 -1
- package/harness/bundles/general/claude-code/scripts/harness_review.py +25 -4
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- 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 +3 -2
- package/harness/bundles/general/codebuddy/harness-plan/checklist.md +18 -79
- package/harness/bundles/general/codebuddy/harness-plan/protocols.md +3 -1
- package/harness/bundles/general/codebuddy/harness-plan/reference.md +37 -8
- 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 +1 -1
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +6 -4
- 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_change.py +25 -7
- package/harness/bundles/general/codebuddy/scripts/harness_context.py +62 -19
- package/harness/bundles/general/codebuddy/scripts/harness_fixback.py +4 -0
- package/harness/bundles/general/codebuddy/scripts/harness_gate.py +208 -72
- package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +43 -0
- package/harness/bundles/general/codebuddy/scripts/harness_paths.py +60 -0
- package/harness/bundles/general/codebuddy/scripts/harness_phase.py +24 -6
- package/harness/bundles/general/codebuddy/scripts/harness_plan_finalize.py +124 -1
- package/harness/bundles/general/codebuddy/scripts/harness_review.py +25 -4
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- 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 +3 -2
- package/harness/bundles/general/codex/harness-plan/checklist.md +18 -79
- package/harness/bundles/general/codex/harness-plan/protocols.md +3 -1
- package/harness/bundles/general/codex/harness-plan/reference.md +37 -8
- 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 +1 -1
- package/harness/bundles/general/codex/harness-run/SKILL.md +6 -4
- 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_change.py +25 -7
- package/harness/bundles/general/codex/scripts/harness_context.py +62 -19
- package/harness/bundles/general/codex/scripts/harness_fixback.py +4 -0
- package/harness/bundles/general/codex/scripts/harness_gate.py +208 -72
- package/harness/bundles/general/codex/scripts/harness_ledger.py +43 -0
- package/harness/bundles/general/codex/scripts/harness_paths.py +60 -0
- package/harness/bundles/general/codex/scripts/harness_phase.py +24 -6
- package/harness/bundles/general/codex/scripts/harness_plan_finalize.py +124 -1
- package/harness/bundles/general/codex/scripts/harness_review.py +25 -4
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- 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 +3 -2
- package/harness/bundles/general/cursor/harness-plan/checklist.md +18 -79
- package/harness/bundles/general/cursor/harness-plan/protocols.md +3 -1
- package/harness/bundles/general/cursor/harness-plan/reference.md +37 -8
- 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 +1 -1
- package/harness/bundles/general/cursor/harness-run/SKILL.md +6 -4
- 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_change.py +25 -7
- package/harness/bundles/general/cursor/scripts/harness_context.py +62 -19
- package/harness/bundles/general/cursor/scripts/harness_fixback.py +4 -0
- package/harness/bundles/general/cursor/scripts/harness_gate.py +208 -72
- package/harness/bundles/general/cursor/scripts/harness_ledger.py +43 -0
- package/harness/bundles/general/cursor/scripts/harness_paths.py +60 -0
- package/harness/bundles/general/cursor/scripts/harness_phase.py +24 -6
- package/harness/bundles/general/cursor/scripts/harness_plan_finalize.py +124 -1
- package/harness/bundles/general/cursor/scripts/harness_review.py +25 -4
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- 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 +3 -2
- package/harness/bundles/java/claude-code/harness-plan/checklist.md +18 -79
- package/harness/bundles/java/claude-code/harness-plan/protocols.md +3 -1
- package/harness/bundles/java/claude-code/harness-plan/reference.md +37 -8
- 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 +1 -1
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +6 -4
- 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_change.py +25 -7
- package/harness/bundles/java/claude-code/scripts/harness_context.py +62 -19
- package/harness/bundles/java/claude-code/scripts/harness_fixback.py +4 -0
- package/harness/bundles/java/claude-code/scripts/harness_gate.py +208 -72
- package/harness/bundles/java/claude-code/scripts/harness_ledger.py +43 -0
- package/harness/bundles/java/claude-code/scripts/harness_paths.py +60 -0
- package/harness/bundles/java/claude-code/scripts/harness_phase.py +24 -6
- package/harness/bundles/java/claude-code/scripts/harness_plan_finalize.py +124 -1
- package/harness/bundles/java/claude-code/scripts/harness_review.py +25 -4
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- 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 +3 -2
- package/harness/bundles/java/codebuddy/harness-plan/checklist.md +18 -79
- package/harness/bundles/java/codebuddy/harness-plan/protocols.md +3 -1
- package/harness/bundles/java/codebuddy/harness-plan/reference.md +37 -8
- 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 +1 -1
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +6 -4
- 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_change.py +25 -7
- package/harness/bundles/java/codebuddy/scripts/harness_context.py +62 -19
- package/harness/bundles/java/codebuddy/scripts/harness_fixback.py +4 -0
- package/harness/bundles/java/codebuddy/scripts/harness_gate.py +208 -72
- package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +43 -0
- package/harness/bundles/java/codebuddy/scripts/harness_paths.py +60 -0
- package/harness/bundles/java/codebuddy/scripts/harness_phase.py +24 -6
- package/harness/bundles/java/codebuddy/scripts/harness_plan_finalize.py +124 -1
- package/harness/bundles/java/codebuddy/scripts/harness_review.py +25 -4
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- 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 +3 -2
- package/harness/bundles/java/codex/harness-plan/checklist.md +18 -79
- package/harness/bundles/java/codex/harness-plan/protocols.md +3 -1
- package/harness/bundles/java/codex/harness-plan/reference.md +37 -8
- 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 +1 -1
- package/harness/bundles/java/codex/harness-run/SKILL.md +6 -4
- 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_change.py +25 -7
- package/harness/bundles/java/codex/scripts/harness_context.py +62 -19
- package/harness/bundles/java/codex/scripts/harness_fixback.py +4 -0
- package/harness/bundles/java/codex/scripts/harness_gate.py +208 -72
- package/harness/bundles/java/codex/scripts/harness_ledger.py +43 -0
- package/harness/bundles/java/codex/scripts/harness_paths.py +60 -0
- package/harness/bundles/java/codex/scripts/harness_phase.py +24 -6
- package/harness/bundles/java/codex/scripts/harness_plan_finalize.py +124 -1
- package/harness/bundles/java/codex/scripts/harness_review.py +25 -4
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- 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 +3 -2
- package/harness/bundles/java/cursor/harness-plan/checklist.md +18 -79
- package/harness/bundles/java/cursor/harness-plan/protocols.md +3 -1
- package/harness/bundles/java/cursor/harness-plan/reference.md +37 -8
- 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 +1 -1
- package/harness/bundles/java/cursor/harness-run/SKILL.md +6 -4
- 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_change.py +25 -7
- package/harness/bundles/java/cursor/scripts/harness_context.py +62 -19
- package/harness/bundles/java/cursor/scripts/harness_fixback.py +4 -0
- package/harness/bundles/java/cursor/scripts/harness_gate.py +208 -72
- package/harness/bundles/java/cursor/scripts/harness_ledger.py +43 -0
- package/harness/bundles/java/cursor/scripts/harness_paths.py +60 -0
- package/harness/bundles/java/cursor/scripts/harness_phase.py +24 -6
- package/harness/bundles/java/cursor/scripts/harness_plan_finalize.py +124 -1
- package/harness/bundles/java/cursor/scripts/harness_review.py +25 -4
- package/harness/manifests/general/claude-code.json +26 -26
- package/harness/manifests/general/codebuddy.json +26 -26
- package/harness/manifests/general/codex.json +26 -26
- package/harness/manifests/general/cursor.json +26 -26
- package/harness/manifests/java/claude-code.json +28 -28
- package/harness/manifests/java/codebuddy.json +28 -28
- package/harness/manifests/java/codex.json +28 -28
- package/harness/manifests/java/cursor.json +28 -28
- package/hunter-workflow-family.json +4 -4
- package/package.json +1 -1
|
@@ -28,6 +28,7 @@ if str(SCRIPTS_DIR) not in sys.path:
|
|
|
28
28
|
sys.path.insert(0, str(SCRIPTS_DIR))
|
|
29
29
|
|
|
30
30
|
import harness_paths # noqa: E402
|
|
31
|
+
import harness_plan_finalize as hpf # noqa: E402
|
|
31
32
|
import harness_profile # noqa: E402
|
|
32
33
|
|
|
33
34
|
|
|
@@ -1629,6 +1630,24 @@ def _scenario_receipt_error(code: str, message: str) -> dict[str, Any]:
|
|
|
1629
1630
|
return {"ok": False, "code": code, "error": message}
|
|
1630
1631
|
|
|
1631
1632
|
|
|
1633
|
+
def resolve_scenario_manifest(manifest: Any) -> dict[str, Any]:
|
|
1634
|
+
"""把 v2 artifact 包装体解成 legacy 形状;legacy 输入原样返回。
|
|
1635
|
+
|
|
1636
|
+
解包规则住在 harness_plan_finalize(它定义了 legacy manifest 的 schema),
|
|
1637
|
+
门禁与本模块共用同一份,两边不会各推一套。
|
|
1638
|
+
|
|
1639
|
+
此前这里只判包装体、一律 fail-closed;更早的时候连判都不判——cmd_record
|
|
1640
|
+
的版本探测初值是 0,包装体探测不出 schemaVersion 就停在 0,
|
|
1641
|
+
`manifest_schema >= 2` 判假,--scenario-receipt-file 的强制要求被静默跳过。
|
|
1642
|
+
|
|
1643
|
+
返回 ``{"ok": True, "manifest": ...}`` 或 ``{"ok": False, "code": ...}``。
|
|
1644
|
+
"""
|
|
1645
|
+
unpacked = hpf.unpack_v2_scenario_manifest(manifest)
|
|
1646
|
+
if unpacked is None:
|
|
1647
|
+
return {"ok": True, "manifest": manifest}
|
|
1648
|
+
return unpacked
|
|
1649
|
+
|
|
1650
|
+
|
|
1632
1651
|
def _resolve_receipt_path(
|
|
1633
1652
|
raw: str, change_dir: Path
|
|
1634
1653
|
) -> tuple[Path | None, list[Path]]:
|
|
@@ -1694,6 +1713,12 @@ def validate_scenario_execution_receipt(
|
|
|
1694
1713
|
)
|
|
1695
1714
|
except (OSError, json.JSONDecodeError) as exc:
|
|
1696
1715
|
return _scenario_receipt_error("SCENARIO_MANIFEST_INVALID", str(exc))
|
|
1716
|
+
resolved = resolve_scenario_manifest(manifest)
|
|
1717
|
+
if not resolved["ok"]:
|
|
1718
|
+
return _scenario_receipt_error(
|
|
1719
|
+
str(resolved["code"]), str(resolved.get("message") or "")
|
|
1720
|
+
)
|
|
1721
|
+
manifest = resolved["manifest"]
|
|
1697
1722
|
if not isinstance(manifest, dict) or not isinstance(manifest.get("scenarios"), list):
|
|
1698
1723
|
return _scenario_receipt_error(
|
|
1699
1724
|
"SCENARIO_MANIFEST_INVALID",
|
|
@@ -2827,6 +2852,15 @@ def cmd_record(args: argparse.Namespace) -> int:
|
|
|
2827
2852
|
as_json=as_json,
|
|
2828
2853
|
error_code="SCENARIO_MANIFEST_INVALID",
|
|
2829
2854
|
)
|
|
2855
|
+
resolved_probe = resolve_scenario_manifest(manifest_probe)
|
|
2856
|
+
if not resolved_probe["ok"]:
|
|
2857
|
+
return emit_error(
|
|
2858
|
+
str(resolved_probe.get("message") or ""),
|
|
2859
|
+
as_json=as_json,
|
|
2860
|
+
error_code=str(resolved_probe["code"]),
|
|
2861
|
+
extra={"artifactType": "scenario_manifest"},
|
|
2862
|
+
)
|
|
2863
|
+
manifest_probe = resolved_probe["manifest"]
|
|
2830
2864
|
raw_schema = (
|
|
2831
2865
|
manifest_probe.get("schemaVersion")
|
|
2832
2866
|
if isinstance(manifest_probe, dict)
|
|
@@ -3064,6 +3098,15 @@ def cmd_scenario_receipt_template(args: argparse.Namespace) -> int:
|
|
|
3064
3098
|
as_json=as_json,
|
|
3065
3099
|
error_code="SCENARIO_MANIFEST_INVALID",
|
|
3066
3100
|
)
|
|
3101
|
+
resolved = resolve_scenario_manifest(manifest)
|
|
3102
|
+
if not resolved["ok"]:
|
|
3103
|
+
return emit_error(
|
|
3104
|
+
str(resolved.get("message") or ""),
|
|
3105
|
+
as_json=as_json,
|
|
3106
|
+
error_code=str(resolved["code"]),
|
|
3107
|
+
extra={"artifactType": "scenario_manifest"},
|
|
3108
|
+
)
|
|
3109
|
+
manifest = resolved["manifest"]
|
|
3067
3110
|
scenarios = manifest.get("scenarios") if isinstance(manifest, dict) else None
|
|
3068
3111
|
if not isinstance(scenarios, list):
|
|
3069
3112
|
return emit_error(
|
|
@@ -34,6 +34,66 @@ if hasattr(sys.stderr, "reconfigure"):
|
|
|
34
34
|
LIFECYCLE_STATUSES = {"draft", "active", "superseded", "archived", "cancelled"}
|
|
35
35
|
CHANGE_CONTEXT_REL = Path("meta") / "change-context.json"
|
|
36
36
|
|
|
37
|
+
# 工作流阶段的唯一权威清单。这里是叶子模块(不 import 任何 harness_*),所以
|
|
38
|
+
# harness_context 与 harness_phase 都能引它而不成环。
|
|
39
|
+
#
|
|
40
|
+
# 此前这份清单在两个模块各写一遍,靠约定保持同步——直到 harness_phase 少了一个
|
|
41
|
+
# merge,worktree 变更走到 merge 阶段就在 target_required_dag 里直接 raise
|
|
42
|
+
# "unsupported reconcile target phase"。同一份事实不该有两个副本。
|
|
43
|
+
WORKFLOW_PHASES = (
|
|
44
|
+
"plan",
|
|
45
|
+
"run",
|
|
46
|
+
"test",
|
|
47
|
+
"review",
|
|
48
|
+
"package",
|
|
49
|
+
"apidoc",
|
|
50
|
+
"submit",
|
|
51
|
+
"merge",
|
|
52
|
+
"archive",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# 出现在阶段位置、但不是工作流阶段的名字。它们是真实存在的:
|
|
56
|
+
# workflow-policy.json 的 skills.*.phase 用 sync/codebase-map/knowledge-query 标注
|
|
57
|
+
# 技能归属,harness_gate.GATE_RELEASE_PHASES 含 release/deploy。把它们与"拼错的
|
|
58
|
+
# 阶段名"区分开,调用方才能既不误判也不硬崩。
|
|
59
|
+
KNOWN_NON_WORKFLOW_PHASES = frozenset({
|
|
60
|
+
"release",
|
|
61
|
+
"deploy",
|
|
62
|
+
"sync",
|
|
63
|
+
"codebase-map",
|
|
64
|
+
"knowledge-query",
|
|
65
|
+
"knowledge-ingest",
|
|
66
|
+
"push",
|
|
67
|
+
"pull",
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
# 旧阶段名 → 现阶段名。阶段合并/改名时在这里登记,读时映射即可让历史
|
|
71
|
+
# gate-policy.json 与 plannedPhases 继续可读,不必迁移已落盘的 change。
|
|
72
|
+
# 目前为空:还没有发生过阶段改名。
|
|
73
|
+
LEGACY_PHASE_ALIASES: dict[str, str] = {}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def resolve_phase_name(phase: Any) -> str | None:
|
|
77
|
+
"""把可能是旧名的阶段解析成当前的工作流阶段名;不是工作流阶段则返回 None。"""
|
|
78
|
+
name = str(phase or "").strip()
|
|
79
|
+
if name in WORKFLOW_PHASES:
|
|
80
|
+
return name
|
|
81
|
+
mapped = LEGACY_PHASE_ALIASES.get(name)
|
|
82
|
+
return mapped if mapped in WORKFLOW_PHASES else None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def classify_phase_name(phase: Any) -> str:
|
|
86
|
+
"""三态判定:``workflow`` | ``non_workflow`` | ``unknown``。
|
|
87
|
+
|
|
88
|
+
调用方需要区分这三者:``workflow`` 照常处理;``non_workflow`` 是别的子系统
|
|
89
|
+
的标注,跳过而不是报错;只有 ``unknown`` 才是真的有问题,值得让人看见。
|
|
90
|
+
"""
|
|
91
|
+
if resolve_phase_name(phase) is not None:
|
|
92
|
+
return "workflow"
|
|
93
|
+
if str(phase or "").strip() in KNOWN_NON_WORKFLOW_PHASES:
|
|
94
|
+
return "non_workflow"
|
|
95
|
+
return "unknown"
|
|
96
|
+
|
|
37
97
|
|
|
38
98
|
def _git_text(cwd: Path, *args: str) -> str | None:
|
|
39
99
|
proc = subprocess.run(
|
|
@@ -33,7 +33,9 @@ import harness_paths as hpaths # noqa: E402
|
|
|
33
33
|
|
|
34
34
|
SCHEMA_VERSION = 1
|
|
35
35
|
CI_METRICS_SCHEMA_VERSION = 1
|
|
36
|
-
|
|
36
|
+
# 唯一权威清单在 harness_paths,harness_context 引的是同一个对象。此前这里另有
|
|
37
|
+
# 一份拷贝,少了 merge,worktree 变更走到 merge 就在 target_required_dag 里硬 raise。
|
|
38
|
+
PHASE_ORDER = hpaths.WORKFLOW_PHASES
|
|
37
39
|
VALIDATION_PHASES = {
|
|
38
40
|
"compile": "run",
|
|
39
41
|
"unitTest": "run",
|
|
@@ -700,8 +702,18 @@ def target_required_dag(policy: dict[str, Any], target_phase: str) -> dict[str,
|
|
|
700
702
|
stage nodes for the target itself are deliberately excluded because their
|
|
701
703
|
``phase.end`` is the result of close, not evidence required before close.
|
|
702
704
|
"""
|
|
703
|
-
|
|
704
|
-
|
|
705
|
+
# 未知阶段名先过读时映射:阶段改名后,历史 change 的 gate-policy.json 与
|
|
706
|
+
# plannedPhases 里仍然是旧名,靠 LEGACY_PHASE_ALIASES 继续可读,不必迁移已落盘
|
|
707
|
+
# 的 change(本仓库没有 change 级 schema 迁移机制,硬 raise 等于让在途变更报废)。
|
|
708
|
+
resolved_target = hpaths.resolve_phase_name(target_phase)
|
|
709
|
+
if resolved_target is None:
|
|
710
|
+
raise ValueError(
|
|
711
|
+
f"unsupported reconcile target phase: {target_phase}; "
|
|
712
|
+
f"已知阶段 {', '.join(PHASE_ORDER)}。"
|
|
713
|
+
"若这是改名前的旧阶段,在 harness_paths.LEGACY_PHASE_ALIASES 登记映射;"
|
|
714
|
+
"若这份 gate-policy.json 本身过期,重跑 harness_gate.py classify 重建"
|
|
715
|
+
)
|
|
716
|
+
target_phase = resolved_target
|
|
705
717
|
dag = policy.get("requiredGateDag")
|
|
706
718
|
if not isinstance(dag, dict) or not isinstance(dag.get("nodes"), list):
|
|
707
719
|
raise ValueError("gate policy missing requiredGateDag; run harness_gate.py classify")
|
|
@@ -718,9 +730,15 @@ def target_required_dag(policy: dict[str, Any], target_phase: str) -> dict[str,
|
|
|
718
730
|
if node_kind == "validation"
|
|
719
731
|
else node_name
|
|
720
732
|
)
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
733
|
+
raw_phase = str(node.get("phase") or inferred_phase or "")
|
|
734
|
+
node_phase = hpaths.resolve_phase_name(raw_phase)
|
|
735
|
+
if node_phase is None:
|
|
736
|
+
raise ValueError(
|
|
737
|
+
f"requiredGateDag node has unsupported phase: {node_id} (phase={raw_phase!r});"
|
|
738
|
+
"旧阶段名在 harness_paths.LEGACY_PHASE_ALIASES 登记映射,"
|
|
739
|
+
"或重跑 harness_gate.py classify 重建这份 gate-policy.json"
|
|
740
|
+
)
|
|
741
|
+
node["phase"] = node_phase
|
|
724
742
|
node_rank = PHASE_ORDER.index(node_phase)
|
|
725
743
|
is_validation = node.get("kind") == "validation" or node_id.startswith(
|
|
726
744
|
"validation:"
|
|
@@ -261,6 +261,127 @@ def scenario_manifest_schema_version(scenarios: list[dict[str, Any]]) -> int:
|
|
|
261
261
|
return 1
|
|
262
262
|
|
|
263
263
|
|
|
264
|
+
# v2 场景键 → 门禁与 ledger 消费的 legacy 键。可执行三元是可选的:缺了只是把
|
|
265
|
+
# manifest 降到 schemaVersion 1(绑不上结构化执行收据),不算缺口。
|
|
266
|
+
_V2_SCENARIO_FIELD_MAP = (
|
|
267
|
+
("scenario_id", "id"),
|
|
268
|
+
("priority", "priority"),
|
|
269
|
+
("required_evidence_kind", "requiredEvidenceKind"),
|
|
270
|
+
("owner_phase", "ownerPhase"),
|
|
271
|
+
)
|
|
272
|
+
_V2_SCENARIO_OPTIONAL_FIELD_MAP = (
|
|
273
|
+
("executable_test_id", "executableTestId"),
|
|
274
|
+
("test_file", "testFile"),
|
|
275
|
+
("test_title", "testTitle"),
|
|
276
|
+
)
|
|
277
|
+
V2_MANIFEST_UNSUPPORTED = "SCENARIO_MANIFEST_V2_UNSUPPORTED"
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def is_v2_scenario_manifest(manifest: Any) -> bool:
|
|
281
|
+
"""v2 plan finalize 派生的 scenario_manifest artifact 包装体。
|
|
282
|
+
|
|
283
|
+
它没有顶层 schemaVersion,场景字段全在 content.scenarios 下且改了名。
|
|
284
|
+
"""
|
|
285
|
+
return (
|
|
286
|
+
isinstance(manifest, dict)
|
|
287
|
+
and manifest.get("artifact_type") == "scenario_manifest"
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def unpack_v2_scenario_manifest(manifest: Any) -> dict[str, Any] | None:
|
|
292
|
+
"""v2 artifact 包装体 → 消费端的 legacy 形状;字段不齐时 fail-closed。
|
|
293
|
+
|
|
294
|
+
返回 None 表示"这不是 v2 包装体",调用方按 legacy 原样处理。否则返回
|
|
295
|
+
``{"ok": True, "manifest": {...}}``(已是 legacy 形状,后续判定逻辑对
|
|
296
|
+
v2 与 legacy 完全一致)或 ``{"ok": False, "code": V2_MANIFEST_UNSUPPORTED}``。
|
|
297
|
+
|
|
298
|
+
这个函数住在 finalizer 里,是因为 legacy manifest 的 schema 本来就由本模块
|
|
299
|
+
定义(``scenario_manifest_schema_version`` / ``PRIORITY_EVIDENCE_KIND``)。
|
|
300
|
+
门禁与 ledger 都 import 它,两边不会各推一套解包规则。
|
|
301
|
+
|
|
302
|
+
为什么必须逐场景校验、不能取键的并集:并集只要有**一条**场景带了
|
|
303
|
+
priority 就算"present",其余缺 priority 的场景会静默落进非必需集,
|
|
304
|
+
``required_ids`` 随之缩水——那正是把证据门禁悄悄关掉的老路子。
|
|
305
|
+
"""
|
|
306
|
+
if not is_v2_scenario_manifest(manifest):
|
|
307
|
+
return None
|
|
308
|
+
content = manifest.get("content")
|
|
309
|
+
raw = content.get("scenarios") if isinstance(content, dict) else None
|
|
310
|
+
if not isinstance(raw, list):
|
|
311
|
+
return {
|
|
312
|
+
"ok": False,
|
|
313
|
+
"code": V2_MANIFEST_UNSUPPORTED,
|
|
314
|
+
"message": "v2 scenario-manifest 的 content.scenarios 必须是数组",
|
|
315
|
+
"missingFields": [legacy for _, legacy in _V2_SCENARIO_FIELD_MAP],
|
|
316
|
+
"artifactType": "scenario_manifest",
|
|
317
|
+
}
|
|
318
|
+
scenarios: list[dict[str, Any]] = []
|
|
319
|
+
missing: set[str] = set()
|
|
320
|
+
for item in raw:
|
|
321
|
+
if not isinstance(item, dict):
|
|
322
|
+
missing.update(legacy for _, legacy in _V2_SCENARIO_FIELD_MAP)
|
|
323
|
+
continue
|
|
324
|
+
mapped: dict[str, Any] = {}
|
|
325
|
+
for source, legacy in _V2_SCENARIO_FIELD_MAP:
|
|
326
|
+
value = item.get(source)
|
|
327
|
+
if not str(value or "").strip():
|
|
328
|
+
missing.add(legacy)
|
|
329
|
+
continue
|
|
330
|
+
mapped[legacy] = value
|
|
331
|
+
for source, legacy in _V2_SCENARIO_OPTIONAL_FIELD_MAP:
|
|
332
|
+
value = item.get(source)
|
|
333
|
+
if str(value or "").strip():
|
|
334
|
+
mapped[legacy] = value
|
|
335
|
+
scenarios.append(mapped)
|
|
336
|
+
if missing:
|
|
337
|
+
return {
|
|
338
|
+
"ok": False,
|
|
339
|
+
"code": V2_MANIFEST_UNSUPPORTED,
|
|
340
|
+
"message": (
|
|
341
|
+
"meta/scenario-manifest.json 是 v2 plan artifact 包装体,"
|
|
342
|
+
"部分场景缺少消费端需要的字段;请在规划阶段补齐后重新发布,"
|
|
343
|
+
"不要手改派生产物"
|
|
344
|
+
),
|
|
345
|
+
"missingFields": sorted(missing),
|
|
346
|
+
"artifactType": "scenario_manifest",
|
|
347
|
+
}
|
|
348
|
+
return {
|
|
349
|
+
"ok": True,
|
|
350
|
+
"manifest": {
|
|
351
|
+
# 与 legacy 同一条规则判版本,不另立一套。
|
|
352
|
+
"schemaVersion": scenario_manifest_schema_version(scenarios),
|
|
353
|
+
"scenarios": scenarios,
|
|
354
|
+
},
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def unpack_v2_implementation_checkpoints(document: Any) -> dict[str, Any] | None:
|
|
359
|
+
"""v2 的 implementation_checkpoints artifact 包装体 → 门禁消费的形状。
|
|
360
|
+
|
|
361
|
+
返回 None 表示"这不是 v2 包装体",调用方按原样处理。
|
|
362
|
+
|
|
363
|
+
v2 的 content 是 ``{tasks, foundation_gate}``,而 ``checkpoint_status`` 找的是
|
|
364
|
+
``checkpoints: [{id, status}]``——找不到就返回 "missing",``foundation_gate_blocks``
|
|
365
|
+
随即放行。也就是说 foundation-gate 对**所有 v2 计划**是静默关闭的。信息本身是够
|
|
366
|
+
的(``foundation_gate`` 就是那个状态),只是形状不同,所以这里解包而不是改文件名
|
|
367
|
+
——与 scenario-manifest 同一模式。
|
|
368
|
+
"""
|
|
369
|
+
if (
|
|
370
|
+
not isinstance(document, dict)
|
|
371
|
+
or document.get("artifact_type") != "implementation_checkpoints"
|
|
372
|
+
):
|
|
373
|
+
return None
|
|
374
|
+
content = document.get("content")
|
|
375
|
+
content = content if isinstance(content, dict) else {}
|
|
376
|
+
status = str(content.get("foundation_gate") or "").strip() or "pending"
|
|
377
|
+
tasks = content.get("tasks")
|
|
378
|
+
return {
|
|
379
|
+
"schemaVersion": 1,
|
|
380
|
+
"checkpoints": [{"id": "foundation-gate", "status": status, "blocking": True}],
|
|
381
|
+
"tasks": tasks if isinstance(tasks, list) else [],
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
|
|
264
385
|
def parse_plan_tasks(plan_path: Path) -> list[dict[str, str]]:
|
|
265
386
|
"""C8: parse plan.md task table rows, extracting optional ownerPhase/implementationDoneWhen/verificationPhase columns.
|
|
266
387
|
|
|
@@ -877,7 +998,9 @@ def _verify_plan_v2(change_dir: Path) -> dict[str, Any] | None:
|
|
|
877
998
|
f"plans/{change_dir.name}-plan.md",
|
|
878
999
|
f"plans/{change_dir.name}-implementation-detail.md",
|
|
879
1000
|
f"plans/{change_dir.name}-test-scenarios.md",
|
|
880
|
-
|
|
1001
|
+
# v2 发布的是派生视图 meta/plan-profile.json,不是 Python classify 写的
|
|
1002
|
+
# meta/gate-policy.json——后者是 run/test 门禁的权威输入,不能被发布覆盖。
|
|
1003
|
+
"meta/plan-profile.json",
|
|
881
1004
|
"meta/worktree.json",
|
|
882
1005
|
}
|
|
883
1006
|
missing_required = sorted(required - set(ownership_paths))
|
|
@@ -194,14 +194,30 @@ def _load_findings(change_dir: Path) -> dict[str, Any] | None:
|
|
|
194
194
|
|
|
195
195
|
|
|
196
196
|
def validate_dispositions(
|
|
197
|
-
doc: Any, known_ids: set[str]
|
|
197
|
+
doc: Any, known_ids: set[str], findings_run_id: str | None = None
|
|
198
198
|
) -> list[str]:
|
|
199
|
+
"""校验处置文档。``findings_run_id`` 给出时,还要求两份 sidecar 同属一轮。
|
|
200
|
+
|
|
201
|
+
runId 以前完全不校验——``write_dispositions`` 直接透传 ``doc.get("runId")``,
|
|
202
|
+
写 ``None`` 都能落盘,整条 sidecar 的强制力全压在 gate 关门时的一行断言上。
|
|
203
|
+
而这条断言防的是 fixback 循环里的跨轮重放:sidecar 是 per-change 单文件、不带
|
|
204
|
+
runId 后缀,第二轮 review 关门时磁盘上躺着第一轮那份(finding 全已 FIXED)。
|
|
205
|
+
在写入端就挡住,比等到关门再拒绝早一整轮。
|
|
206
|
+
"""
|
|
199
207
|
problems: list[str] = []
|
|
200
208
|
if not isinstance(doc, dict):
|
|
201
209
|
return ["dispositions document must be an object"]
|
|
210
|
+
run_id = doc.get("runId")
|
|
211
|
+
if not isinstance(run_id, str) or not run_id.strip():
|
|
212
|
+
problems.append("runId is required")
|
|
213
|
+
elif findings_run_id is not None and run_id != findings_run_id:
|
|
214
|
+
problems.append(
|
|
215
|
+
f"runId {run_id} does not match review findings runId {findings_run_id}"
|
|
216
|
+
)
|
|
202
217
|
dispositions = doc.get("dispositions")
|
|
203
218
|
if not isinstance(dispositions, list):
|
|
204
|
-
|
|
219
|
+
problems.append("dispositions must be a list")
|
|
220
|
+
return problems
|
|
205
221
|
for index, item in enumerate(dispositions):
|
|
206
222
|
if not isinstance(item, dict):
|
|
207
223
|
problems.append(f"dispositions[{index}] must be an object")
|
|
@@ -226,12 +242,17 @@ def write_dispositions(change_dir: Path, doc: dict[str, Any]) -> dict[str, Any]:
|
|
|
226
242
|
f.get("id") for f in (findings_doc or {}).get("findings", [])
|
|
227
243
|
if isinstance(f, dict)
|
|
228
244
|
}
|
|
229
|
-
|
|
245
|
+
findings_run_id = (findings_doc or {}).get("runId")
|
|
246
|
+
problems = validate_dispositions(
|
|
247
|
+
doc,
|
|
248
|
+
known_ids,
|
|
249
|
+
findings_run_id if isinstance(findings_run_id, str) else None,
|
|
250
|
+
)
|
|
230
251
|
if problems:
|
|
231
252
|
return {"ok": False, "code": "DISPOSITIONS_INVALID", "problems": problems}
|
|
232
253
|
payload = {
|
|
233
254
|
"schemaVersion": 1,
|
|
234
|
-
"runId": doc
|
|
255
|
+
"runId": doc["runId"],
|
|
235
256
|
"dispositions": doc["dispositions"],
|
|
236
257
|
}
|
|
237
258
|
out = dispositions_path(change_dir)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"adapter": "claude-code",
|
|
5
5
|
"bundle_version": "0.2.73",
|
|
6
6
|
"requires": {
|
|
7
|
-
"minimumCliVersion": "0.2.
|
|
7
|
+
"minimumCliVersion": "0.2.92",
|
|
8
8
|
"capabilities": [
|
|
9
9
|
"sync@2",
|
|
10
10
|
"rules-sync@1",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
{
|
|
27
27
|
"path": ".harness-build.json",
|
|
28
|
-
"sha256": "
|
|
28
|
+
"sha256": "3dd6ddcc89f89ab3e51d7b2d1f7415d79ad897c72d29676ed59178b4d5636233"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"path": "agents/harness-evaluator.md",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
"path": "harness-archive/SKILL.md",
|
|
100
|
-
"sha256": "
|
|
100
|
+
"sha256": "4ffdd943d3659f3bee25d5d8949b930f8e1eed45069dbf8fae5c5a593eeceef8"
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
"path": "harness-archive/templates/summary-data-template.json",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"path": "harness-codebase-map/SKILL.md",
|
|
116
|
-
"sha256": "
|
|
116
|
+
"sha256": "77ea556fce28dd30d5463318c066c1e35d48eb1cd9c0285f4097de7d094f2b29"
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
119
|
"path": "harness-codebase-map/templates/ARCHITECTURE.md",
|
|
@@ -153,35 +153,35 @@
|
|
|
153
153
|
},
|
|
154
154
|
{
|
|
155
155
|
"path": "harness-knowledge-ingest/SKILL.md",
|
|
156
|
-
"sha256": "
|
|
156
|
+
"sha256": "67e4f63587f6b2c17820c6c5f9625f702de8b902de1cb38ccbcd2ecf362d44df"
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
"path": "harness-knowledge-query/SKILL.md",
|
|
160
|
-
"sha256": "
|
|
160
|
+
"sha256": "25f165ad7227a348320c6956850584d83bc9bd6267126f32c7f8e2f866a6b885"
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
163
|
"path": "harness-plan/checklist.md",
|
|
164
|
-
"sha256": "
|
|
164
|
+
"sha256": "42eefa0a350a15efab18d9fe03adb019f17eadf0b6c9d797fb80ad05842a22aa"
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"path": "harness-plan/protocols.md",
|
|
168
|
-
"sha256": "
|
|
168
|
+
"sha256": "ee15618cbe4005ec1efd5ae91b0105920b929a9eedba8dffd29183efadf52485"
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
171
|
"path": "harness-plan/reference.md",
|
|
172
|
-
"sha256": "
|
|
172
|
+
"sha256": "a10e417269d4993699a4a1d53ffd4f0c8296231a0c5e468630da3d10809a1d93"
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
175
|
"path": "harness-plan/SKILL.md",
|
|
176
|
-
"sha256": "
|
|
176
|
+
"sha256": "11d0cf7d378e23d95f561c445cd71f5f4a04bce921955e2e6056d67b3a60f564"
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
179
|
"path": "harness-pull/SKILL.md",
|
|
180
|
-
"sha256": "
|
|
180
|
+
"sha256": "b4c52d0a2479557a9e45c18513c6cb4cbe06e0ef4c0681a7bdcaacad1d403aab"
|
|
181
181
|
},
|
|
182
182
|
{
|
|
183
183
|
"path": "harness-push/SKILL.md",
|
|
184
|
-
"sha256": "
|
|
184
|
+
"sha256": "534bf14d352626ca5d9cd3eb8c8b0873cb45235e142abe8183f7f8292f291091"
|
|
185
185
|
},
|
|
186
186
|
{
|
|
187
187
|
"path": "harness-review/checklist.md",
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
},
|
|
198
198
|
{
|
|
199
199
|
"path": "harness-review/SKILL.md",
|
|
200
|
-
"sha256": "
|
|
200
|
+
"sha256": "339f54dd65a69d2e16eea8a99bd6e44056f6f84f4f4b7fb07ee4943e5273fc83"
|
|
201
201
|
},
|
|
202
202
|
{
|
|
203
203
|
"path": "harness-run/checklist.md",
|
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
},
|
|
214
214
|
{
|
|
215
215
|
"path": "harness-run/SKILL.md",
|
|
216
|
-
"sha256": "
|
|
216
|
+
"sha256": "3347cd844c41dbf3161375358ee73c1f4d3a804cd8427e58d5ef044c1892141c"
|
|
217
217
|
},
|
|
218
218
|
{
|
|
219
219
|
"path": "harness-submit/checklist.md",
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
},
|
|
226
226
|
{
|
|
227
227
|
"path": "harness-submit/SKILL.md",
|
|
228
|
-
"sha256": "
|
|
228
|
+
"sha256": "e232d9529f4e1c77e757606c3498fd20c44d60a2c81e3478b716fefc9a66c291"
|
|
229
229
|
},
|
|
230
230
|
{
|
|
231
231
|
"path": "harness-sync/reference.md",
|
|
@@ -233,7 +233,7 @@
|
|
|
233
233
|
},
|
|
234
234
|
{
|
|
235
235
|
"path": "harness-sync/SKILL.md",
|
|
236
|
-
"sha256": "
|
|
236
|
+
"sha256": "81eca1aa726fce88aeeffa513be0b050edc7102a2215fb6c7cd5c601ea048653"
|
|
237
237
|
},
|
|
238
238
|
{
|
|
239
239
|
"path": "harness-test/checklist.md",
|
|
@@ -257,7 +257,7 @@
|
|
|
257
257
|
},
|
|
258
258
|
{
|
|
259
259
|
"path": "harness-test/SKILL.md",
|
|
260
|
-
"sha256": "
|
|
260
|
+
"sha256": "1045385d042fb625bca663068cd2505e73539437e5a7e5e86e4081562df3b630"
|
|
261
261
|
},
|
|
262
262
|
{
|
|
263
263
|
"path": "protocols/archive-report-protocol.md",
|
|
@@ -333,7 +333,7 @@
|
|
|
333
333
|
},
|
|
334
334
|
{
|
|
335
335
|
"path": "scripts/harness_change.py",
|
|
336
|
-
"sha256": "
|
|
336
|
+
"sha256": "9d35cfb6184028ee03c7d574a6d24b33f8cc437ba5c3dae9a0487d50566bda1f"
|
|
337
337
|
},
|
|
338
338
|
{
|
|
339
339
|
"path": "scripts/harness_check_gate.py",
|
|
@@ -341,7 +341,7 @@
|
|
|
341
341
|
},
|
|
342
342
|
{
|
|
343
343
|
"path": "scripts/harness_context.py",
|
|
344
|
-
"sha256": "
|
|
344
|
+
"sha256": "23572ea0c3455812a5998448e4c90afe9ea7d3a37f15c893c718007ad3c5c886"
|
|
345
345
|
},
|
|
346
346
|
{
|
|
347
347
|
"path": "scripts/harness_deploy.py",
|
|
@@ -369,11 +369,11 @@
|
|
|
369
369
|
},
|
|
370
370
|
{
|
|
371
371
|
"path": "scripts/harness_fixback.py",
|
|
372
|
-
"sha256": "
|
|
372
|
+
"sha256": "dda0d6d836fe4aaaf7ba4cbf888f921c9e1800a0d4f17ee8f7e0e3ac19dd4cbc"
|
|
373
373
|
},
|
|
374
374
|
{
|
|
375
375
|
"path": "scripts/harness_gate.py",
|
|
376
|
-
"sha256": "
|
|
376
|
+
"sha256": "447a7339b87cbf134a570a0119b697766f1ee3e703dce497e5f3763ad016cb68"
|
|
377
377
|
},
|
|
378
378
|
{
|
|
379
379
|
"path": "scripts/harness_headless.py",
|
|
@@ -389,7 +389,7 @@
|
|
|
389
389
|
},
|
|
390
390
|
{
|
|
391
391
|
"path": "scripts/harness_ledger.py",
|
|
392
|
-
"sha256": "
|
|
392
|
+
"sha256": "52caa7106480074f1e2ee0122fa6f194cf852805bfd562073ad2fc79ba666514"
|
|
393
393
|
},
|
|
394
394
|
{
|
|
395
395
|
"path": "scripts/harness_migration_head.py",
|
|
@@ -401,11 +401,11 @@
|
|
|
401
401
|
},
|
|
402
402
|
{
|
|
403
403
|
"path": "scripts/harness_paths.py",
|
|
404
|
-
"sha256": "
|
|
404
|
+
"sha256": "bdd20fce04754664f33ceb838a5fa49ddcbf6e507a7017850cacc345b5564a77"
|
|
405
405
|
},
|
|
406
406
|
{
|
|
407
407
|
"path": "scripts/harness_phase.py",
|
|
408
|
-
"sha256": "
|
|
408
|
+
"sha256": "7dc52174d1dc1b3ce8d3c4ebb3f61dd5e1058a77b36d44007ed04db949eaa392"
|
|
409
409
|
},
|
|
410
410
|
{
|
|
411
411
|
"path": "scripts/harness_plan_aggregate.py",
|
|
@@ -413,7 +413,7 @@
|
|
|
413
413
|
},
|
|
414
414
|
{
|
|
415
415
|
"path": "scripts/harness_plan_finalize.py",
|
|
416
|
-
"sha256": "
|
|
416
|
+
"sha256": "0cb683d26bb9af86cfe4a9c019d1fc20447fa90eb12fb31377bd1d7e4740c4d3"
|
|
417
417
|
},
|
|
418
418
|
{
|
|
419
419
|
"path": "scripts/harness_preflight.py",
|
|
@@ -437,7 +437,7 @@
|
|
|
437
437
|
},
|
|
438
438
|
{
|
|
439
439
|
"path": "scripts/harness_review.py",
|
|
440
|
-
"sha256": "
|
|
440
|
+
"sha256": "c3c591323846bee24afc13ba0ab4eb275233eff84f57c1bb5d155a453bd127db"
|
|
441
441
|
},
|
|
442
442
|
{
|
|
443
443
|
"path": "scripts/harness_runtime.py",
|