@hunter-harness/workflow-harness 0.2.66 → 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 +5 -5
- package/harness/bundles/general/claude-code/harness-plan/reference.md +35 -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_events_sync.py +213 -4
- 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 +5 -5
- package/harness/bundles/general/codebuddy/harness-plan/reference.md +35 -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_events_sync.py +213 -4
- 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 +5 -5
- package/harness/bundles/general/codex/harness-plan/reference.md +35 -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_events_sync.py +213 -4
- 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 +5 -5
- package/harness/bundles/general/cursor/harness-plan/reference.md +35 -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_events_sync.py +213 -4
- 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 +5 -5
- package/harness/bundles/java/claude-code/harness-plan/reference.md +35 -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_events_sync.py +213 -4
- 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 +5 -5
- package/harness/bundles/java/codebuddy/harness-plan/reference.md +35 -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_events_sync.py +213 -4
- 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 +5 -5
- package/harness/bundles/java/codex/harness-plan/reference.md +35 -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_events_sync.py +213 -4
- 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 +5 -5
- package/harness/bundles/java/cursor/harness-plan/reference.md +35 -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_events_sync.py +213 -4
- package/harness/bundles/java/cursor/scripts/harness_plan_finalize.py +119 -0
- package/harness/manifests/general/claude-code.json +28 -18
- package/harness/manifests/general/codebuddy.json +28 -18
- package/harness/manifests/general/codex.json +28 -18
- package/harness/manifests/general/cursor.json +28 -18
- package/harness/manifests/java/claude-code.json +30 -20
- package/harness/manifests/java/codebuddy.json +30 -20
- package/harness/manifests/java/codex.json +30 -20
- package/harness/manifests/java/cursor.json +30 -20
- package/hunter-workflow-family.json +11 -7
- package/package.json +1 -1
|
@@ -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:
|