@hunter-harness/workflow-harness 0.2.15 → 0.2.17
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/CONTEXT.md +14 -1
- package/harness/bundles/general/claude-code/README.md +1 -1
- package/harness/bundles/general/claude-code/harness-archive/SKILL.md +7 -4
- package/harness/bundles/general/claude-code/harness-archive/reference.md +1 -1
- package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +4 -2
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +16 -1
- package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +4 -2
- package/harness/bundles/general/claude-code/harness-plan/SKILL.md +8 -4
- package/harness/bundles/general/claude-code/harness-plan/checklist.md +5 -5
- package/harness/bundles/general/claude-code/harness-review/SKILL.md +5 -2
- package/harness/bundles/general/claude-code/harness-review/reference.md +13 -0
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +7 -3
- package/harness/bundles/general/claude-code/harness-run/checklist.md +4 -4
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +6 -3
- package/harness/bundles/general/claude-code/harness-submit/checklist.md +5 -5
- package/harness/bundles/general/claude-code/harness-submit/reference.md +3 -3
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +4 -2
- package/harness/bundles/general/claude-code/harness-sync/reference.md +1 -1
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +7 -4
- package/harness/bundles/general/claude-code/harness-test/checklist.md +8 -5
- package/harness/bundles/general/claude-code/harness-test/pitfalls.md +1 -1
- package/harness/bundles/general/claude-code/harness-test/reference.md +28 -13
- package/harness/bundles/general/claude-code/protocols/submit-protocol.md +1 -1
- package/harness/bundles/general/claude-code/scripts/harness_deploy.py +7 -0
- package/harness/bundles/general/claude-code/scripts/harness_gate.py +75 -0
- package/harness/bundles/general/claude-code/scripts/harness_integration.py +64 -2
- package/harness/bundles/general/claude-code/scripts/harness_ledger.py +70 -3
- package/harness/bundles/general/claude-code/scripts/harness_paths.py +17 -0
- package/harness/bundles/general/claude-code/scripts/harness_plan_finalize.py +306 -7
- package/harness/bundles/general/claude-code/scripts/harness_profile.py +58 -7
- package/harness/bundles/general/claude-code/scripts/harness_review.py +107 -0
- package/harness/bundles/general/claude-code/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/CONTEXT.md +14 -1
- package/harness/bundles/general/codebuddy/README.md +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +7 -4
- package/harness/bundles/general/codebuddy/harness-archive/reference.md +1 -1
- package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +4 -2
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +16 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +4 -2
- package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +8 -4
- package/harness/bundles/general/codebuddy/harness-plan/checklist.md +5 -5
- package/harness/bundles/general/codebuddy/harness-review/SKILL.md +5 -2
- package/harness/bundles/general/codebuddy/harness-review/reference.md +13 -0
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +7 -3
- package/harness/bundles/general/codebuddy/harness-run/checklist.md +4 -4
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +6 -3
- package/harness/bundles/general/codebuddy/harness-submit/checklist.md +5 -5
- package/harness/bundles/general/codebuddy/harness-submit/reference.md +3 -3
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +4 -2
- package/harness/bundles/general/codebuddy/harness-sync/reference.md +1 -1
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +7 -4
- package/harness/bundles/general/codebuddy/harness-test/checklist.md +8 -5
- package/harness/bundles/general/codebuddy/harness-test/pitfalls.md +1 -1
- package/harness/bundles/general/codebuddy/harness-test/reference.md +28 -13
- package/harness/bundles/general/codebuddy/protocols/submit-protocol.md +1 -1
- package/harness/bundles/general/codebuddy/scripts/harness_deploy.py +7 -0
- package/harness/bundles/general/codebuddy/scripts/harness_gate.py +75 -0
- package/harness/bundles/general/codebuddy/scripts/harness_integration.py +64 -2
- package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +70 -3
- package/harness/bundles/general/codebuddy/scripts/harness_paths.py +17 -0
- package/harness/bundles/general/codebuddy/scripts/harness_plan_finalize.py +306 -7
- package/harness/bundles/general/codebuddy/scripts/harness_profile.py +58 -7
- package/harness/bundles/general/codebuddy/scripts/harness_review.py +107 -0
- package/harness/bundles/general/codebuddy/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/CONTEXT.md +14 -1
- package/harness/bundles/general/codex/README.md +1 -1
- package/harness/bundles/general/codex/harness-archive/SKILL.md +7 -4
- package/harness/bundles/general/codex/harness-archive/reference.md +1 -1
- package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +4 -2
- package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +16 -1
- package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +4 -2
- package/harness/bundles/general/codex/harness-plan/SKILL.md +8 -4
- package/harness/bundles/general/codex/harness-plan/checklist.md +5 -5
- package/harness/bundles/general/codex/harness-review/SKILL.md +5 -2
- package/harness/bundles/general/codex/harness-review/reference.md +13 -0
- package/harness/bundles/general/codex/harness-run/SKILL.md +7 -3
- package/harness/bundles/general/codex/harness-run/checklist.md +4 -4
- package/harness/bundles/general/codex/harness-submit/SKILL.md +6 -3
- package/harness/bundles/general/codex/harness-submit/checklist.md +5 -5
- package/harness/bundles/general/codex/harness-submit/reference.md +3 -3
- package/harness/bundles/general/codex/harness-sync/SKILL.md +4 -2
- package/harness/bundles/general/codex/harness-sync/reference.md +1 -1
- package/harness/bundles/general/codex/harness-test/SKILL.md +7 -4
- package/harness/bundles/general/codex/harness-test/checklist.md +8 -5
- package/harness/bundles/general/codex/harness-test/pitfalls.md +1 -1
- package/harness/bundles/general/codex/harness-test/reference.md +28 -13
- package/harness/bundles/general/codex/protocols/submit-protocol.md +1 -1
- package/harness/bundles/general/codex/scripts/harness_deploy.py +7 -0
- package/harness/bundles/general/codex/scripts/harness_gate.py +75 -0
- package/harness/bundles/general/codex/scripts/harness_integration.py +64 -2
- package/harness/bundles/general/codex/scripts/harness_ledger.py +70 -3
- package/harness/bundles/general/codex/scripts/harness_paths.py +17 -0
- package/harness/bundles/general/codex/scripts/harness_plan_finalize.py +306 -7
- package/harness/bundles/general/codex/scripts/harness_profile.py +58 -7
- package/harness/bundles/general/codex/scripts/harness_review.py +107 -0
- package/harness/bundles/general/codex/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/CONTEXT.md +14 -1
- package/harness/bundles/general/cursor/README.md +1 -1
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +7 -4
- package/harness/bundles/general/cursor/harness-archive/reference.md +1 -1
- package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +4 -2
- package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +16 -1
- package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +4 -2
- package/harness/bundles/general/cursor/harness-plan/SKILL.md +8 -4
- package/harness/bundles/general/cursor/harness-plan/checklist.md +5 -5
- package/harness/bundles/general/cursor/harness-review/SKILL.md +5 -2
- package/harness/bundles/general/cursor/harness-review/reference.md +13 -0
- package/harness/bundles/general/cursor/harness-run/SKILL.md +7 -3
- package/harness/bundles/general/cursor/harness-run/checklist.md +4 -4
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +6 -3
- package/harness/bundles/general/cursor/harness-submit/checklist.md +5 -5
- package/harness/bundles/general/cursor/harness-submit/reference.md +3 -3
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +4 -2
- package/harness/bundles/general/cursor/harness-sync/reference.md +1 -1
- package/harness/bundles/general/cursor/harness-test/SKILL.md +7 -4
- package/harness/bundles/general/cursor/harness-test/checklist.md +8 -5
- package/harness/bundles/general/cursor/harness-test/pitfalls.md +1 -1
- package/harness/bundles/general/cursor/harness-test/reference.md +28 -13
- package/harness/bundles/general/cursor/protocols/submit-protocol.md +1 -1
- package/harness/bundles/general/cursor/scripts/harness_deploy.py +7 -0
- package/harness/bundles/general/cursor/scripts/harness_gate.py +75 -0
- package/harness/bundles/general/cursor/scripts/harness_integration.py +64 -2
- package/harness/bundles/general/cursor/scripts/harness_ledger.py +70 -3
- package/harness/bundles/general/cursor/scripts/harness_paths.py +17 -0
- package/harness/bundles/general/cursor/scripts/harness_plan_finalize.py +306 -7
- package/harness/bundles/general/cursor/scripts/harness_profile.py +58 -7
- package/harness/bundles/general/cursor/scripts/harness_review.py +107 -0
- package/harness/bundles/general/cursor/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/CONTEXT.md +14 -1
- package/harness/bundles/java/claude-code/README.md +1 -1
- package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +5 -2
- package/harness/bundles/java/claude-code/harness-archive/SKILL.md +7 -4
- package/harness/bundles/java/claude-code/harness-archive/reference.md +1 -1
- package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +4 -2
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +16 -1
- package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +4 -2
- package/harness/bundles/java/claude-code/harness-package/SKILL.md +5 -2
- package/harness/bundles/java/claude-code/harness-package/checklist.md +4 -4
- package/harness/bundles/java/claude-code/harness-plan/SKILL.md +8 -4
- package/harness/bundles/java/claude-code/harness-plan/checklist.md +5 -5
- package/harness/bundles/java/claude-code/harness-review/SKILL.md +5 -2
- package/harness/bundles/java/claude-code/harness-review/reference.md +13 -0
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +7 -3
- package/harness/bundles/java/claude-code/harness-run/checklist.md +4 -4
- package/harness/bundles/java/claude-code/harness-submit/SKILL.md +6 -3
- package/harness/bundles/java/claude-code/harness-submit/checklist.md +5 -5
- package/harness/bundles/java/claude-code/harness-submit/reference.md +3 -3
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +4 -2
- package/harness/bundles/java/claude-code/harness-sync/reference.md +1 -1
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +8 -5
- package/harness/bundles/java/claude-code/harness-test/pitfalls.md +1 -1
- package/harness/bundles/java/claude-code/harness-test/reference.md +1 -1
- package/harness/bundles/java/claude-code/protocols/submit-protocol.md +1 -1
- package/harness/bundles/java/claude-code/scripts/harness_deploy.py +7 -0
- package/harness/bundles/java/claude-code/scripts/harness_gate.py +75 -0
- package/harness/bundles/java/claude-code/scripts/harness_integration.py +64 -2
- package/harness/bundles/java/claude-code/scripts/harness_ledger.py +70 -3
- package/harness/bundles/java/claude-code/scripts/harness_paths.py +17 -0
- package/harness/bundles/java/claude-code/scripts/harness_plan_finalize.py +306 -7
- package/harness/bundles/java/claude-code/scripts/harness_profile.py +58 -7
- package/harness/bundles/java/claude-code/scripts/harness_review.py +107 -0
- package/harness/bundles/java/claude-code/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/CONTEXT.md +14 -1
- package/harness/bundles/java/codebuddy/README.md +1 -1
- package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +5 -2
- package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +7 -4
- package/harness/bundles/java/codebuddy/harness-archive/reference.md +1 -1
- package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +4 -2
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +16 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +4 -2
- package/harness/bundles/java/codebuddy/harness-package/SKILL.md +5 -2
- package/harness/bundles/java/codebuddy/harness-package/checklist.md +4 -4
- package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +8 -4
- package/harness/bundles/java/codebuddy/harness-plan/checklist.md +5 -5
- package/harness/bundles/java/codebuddy/harness-review/SKILL.md +5 -2
- package/harness/bundles/java/codebuddy/harness-review/reference.md +13 -0
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +7 -3
- package/harness/bundles/java/codebuddy/harness-run/checklist.md +4 -4
- package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +6 -3
- package/harness/bundles/java/codebuddy/harness-submit/checklist.md +5 -5
- package/harness/bundles/java/codebuddy/harness-submit/reference.md +3 -3
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +4 -2
- package/harness/bundles/java/codebuddy/harness-sync/reference.md +1 -1
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +8 -5
- package/harness/bundles/java/codebuddy/harness-test/pitfalls.md +1 -1
- package/harness/bundles/java/codebuddy/harness-test/reference.md +1 -1
- package/harness/bundles/java/codebuddy/protocols/submit-protocol.md +1 -1
- package/harness/bundles/java/codebuddy/scripts/harness_deploy.py +7 -0
- package/harness/bundles/java/codebuddy/scripts/harness_gate.py +75 -0
- package/harness/bundles/java/codebuddy/scripts/harness_integration.py +64 -2
- package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +70 -3
- package/harness/bundles/java/codebuddy/scripts/harness_paths.py +17 -0
- package/harness/bundles/java/codebuddy/scripts/harness_plan_finalize.py +306 -7
- package/harness/bundles/java/codebuddy/scripts/harness_profile.py +58 -7
- package/harness/bundles/java/codebuddy/scripts/harness_review.py +107 -0
- package/harness/bundles/java/codebuddy/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/CONTEXT.md +14 -1
- package/harness/bundles/java/codex/README.md +1 -1
- package/harness/bundles/java/codex/harness-apidoc/SKILL.md +5 -2
- package/harness/bundles/java/codex/harness-archive/SKILL.md +7 -4
- package/harness/bundles/java/codex/harness-archive/reference.md +1 -1
- package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +4 -2
- package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +16 -1
- package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +4 -2
- package/harness/bundles/java/codex/harness-package/SKILL.md +5 -2
- package/harness/bundles/java/codex/harness-package/checklist.md +4 -4
- package/harness/bundles/java/codex/harness-plan/SKILL.md +8 -4
- package/harness/bundles/java/codex/harness-plan/checklist.md +5 -5
- package/harness/bundles/java/codex/harness-review/SKILL.md +5 -2
- package/harness/bundles/java/codex/harness-review/reference.md +13 -0
- package/harness/bundles/java/codex/harness-run/SKILL.md +7 -3
- package/harness/bundles/java/codex/harness-run/checklist.md +4 -4
- package/harness/bundles/java/codex/harness-submit/SKILL.md +6 -3
- package/harness/bundles/java/codex/harness-submit/checklist.md +5 -5
- package/harness/bundles/java/codex/harness-submit/reference.md +3 -3
- package/harness/bundles/java/codex/harness-sync/SKILL.md +4 -2
- package/harness/bundles/java/codex/harness-sync/reference.md +1 -1
- package/harness/bundles/java/codex/harness-test/SKILL.md +8 -5
- package/harness/bundles/java/codex/harness-test/pitfalls.md +1 -1
- package/harness/bundles/java/codex/harness-test/reference.md +1 -1
- package/harness/bundles/java/codex/protocols/submit-protocol.md +1 -1
- package/harness/bundles/java/codex/scripts/harness_deploy.py +7 -0
- package/harness/bundles/java/codex/scripts/harness_gate.py +75 -0
- package/harness/bundles/java/codex/scripts/harness_integration.py +64 -2
- package/harness/bundles/java/codex/scripts/harness_ledger.py +70 -3
- package/harness/bundles/java/codex/scripts/harness_paths.py +17 -0
- package/harness/bundles/java/codex/scripts/harness_plan_finalize.py +306 -7
- package/harness/bundles/java/codex/scripts/harness_profile.py +58 -7
- package/harness/bundles/java/codex/scripts/harness_review.py +107 -0
- package/harness/bundles/java/codex/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/CONTEXT.md +14 -1
- package/harness/bundles/java/cursor/README.md +1 -1
- package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +5 -2
- package/harness/bundles/java/cursor/harness-archive/SKILL.md +7 -4
- package/harness/bundles/java/cursor/harness-archive/reference.md +1 -1
- package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +4 -2
- package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +16 -1
- package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +4 -2
- package/harness/bundles/java/cursor/harness-package/SKILL.md +5 -2
- package/harness/bundles/java/cursor/harness-package/checklist.md +4 -4
- package/harness/bundles/java/cursor/harness-plan/SKILL.md +8 -4
- package/harness/bundles/java/cursor/harness-plan/checklist.md +5 -5
- package/harness/bundles/java/cursor/harness-review/SKILL.md +5 -2
- package/harness/bundles/java/cursor/harness-review/reference.md +13 -0
- package/harness/bundles/java/cursor/harness-run/SKILL.md +7 -3
- package/harness/bundles/java/cursor/harness-run/checklist.md +4 -4
- package/harness/bundles/java/cursor/harness-submit/SKILL.md +6 -3
- package/harness/bundles/java/cursor/harness-submit/checklist.md +5 -5
- package/harness/bundles/java/cursor/harness-submit/reference.md +3 -3
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +4 -2
- package/harness/bundles/java/cursor/harness-sync/reference.md +1 -1
- package/harness/bundles/java/cursor/harness-test/SKILL.md +8 -5
- package/harness/bundles/java/cursor/harness-test/pitfalls.md +1 -1
- package/harness/bundles/java/cursor/harness-test/reference.md +1 -1
- package/harness/bundles/java/cursor/protocols/submit-protocol.md +1 -1
- package/harness/bundles/java/cursor/scripts/harness_deploy.py +7 -0
- package/harness/bundles/java/cursor/scripts/harness_gate.py +75 -0
- package/harness/bundles/java/cursor/scripts/harness_integration.py +64 -2
- package/harness/bundles/java/cursor/scripts/harness_ledger.py +70 -3
- package/harness/bundles/java/cursor/scripts/harness_paths.py +17 -0
- package/harness/bundles/java/cursor/scripts/harness_plan_finalize.py +306 -7
- package/harness/bundles/java/cursor/scripts/harness_profile.py +58 -7
- package/harness/bundles/java/cursor/scripts/harness_review.py +107 -0
- package/harness/bundles/java/cursor/scripts/harness_test_cleanup.py +175 -0
- package/harness/manifests/general/claude-code.json +38 -34
- package/harness/manifests/general/codebuddy.json +38 -34
- package/harness/manifests/general/codex.json +38 -34
- package/harness/manifests/general/cursor.json +38 -34
- package/harness/manifests/java/claude-code.json +40 -36
- package/harness/manifests/java/codebuddy.json +40 -36
- package/harness/manifests/java/codex.json +40 -36
- package/harness/manifests/java/cursor.json +40 -36
- package/hunter-workflow-family.json +2 -2
- package/package.json +1 -1
|
@@ -19,7 +19,7 @@ description: harness-run 的执行检查清单。仅在编码执行时读取。
|
|
|
19
19
|
- [ ] worktree 创建命令必须使用 PowerShell:`git worktree add ...`
|
|
20
20
|
- [ ] 创建后验证 `<adapter-worktree-root>/<change-name>/.git` 存在;Codex 必须是 `.codex/worktrees/<change-name>`
|
|
21
21
|
- [ ] 创建成功后更新 `meta/worktree.json` 的 `created=true/createdAt/createdBy`
|
|
22
|
-
- [ ] 创建失败 → 停止,或
|
|
22
|
+
- [ ] 创建失败 → 停止,或 blocking user confirmation 询问是否改为主目录执行
|
|
23
23
|
- [ ] 禁止 `requested=true && worktree 不存在` 时直接主目录执行
|
|
24
24
|
- [ ] 记录 `projectRoot / worktreeRoot / stateDir`
|
|
25
25
|
|
|
@@ -46,7 +46,7 @@ description: harness-run 的执行检查清单。仅在编码执行时读取。
|
|
|
46
46
|
- [ ] 统计任务数量和涉及模块数
|
|
47
47
|
- [ ] 如果处于 `--fixback` 模式,将 RED/YELLOW fixback 条目映射为本轮变更簇,并记录 `fixback: applied`
|
|
48
48
|
- [ ] 默认 Inline Execution;`--subagent` / `--inline` 参数覆盖
|
|
49
|
-
- [ ] **禁止**因任务数/模块数
|
|
49
|
+
- [ ] **禁止**因任务数/模块数 blocking user confirmation 选择执行模式
|
|
50
50
|
|
|
51
51
|
## 步骤 0.5:测试基础设施探测(⚠️ 必须先于任何 TDD 降级结论)
|
|
52
52
|
|
|
@@ -67,7 +67,7 @@ description: harness-run 的执行检查清单。仅在编码执行时读取。
|
|
|
67
67
|
> 如果 run 开始前检测到已有未提交变更,必须执行此步骤。
|
|
68
68
|
|
|
69
69
|
- [ ] 检查 git status 是否有 run 前的预存变更
|
|
70
|
-
- [ ] 如果有预存变更 → 使用
|
|
70
|
+
- [ ] 如果有预存变更 → 使用 blocking user confirmation 询问用户处理方式(保留/暂存/终止)
|
|
71
71
|
- [ ] 用户选择保留 → 创建 `.harness/changes/<change>/pre-existing-files.json`(文件列表 + diff hash + 用户选择)
|
|
72
72
|
- [ ] 用户选择保留 → 创建 `.harness/changes/<change>/pre-existing-diff.patch`(完整 diff 备份)
|
|
73
73
|
- [ ] 在执行日志中记录预存变更检测结果和用户选择
|
|
@@ -223,7 +223,7 @@ description: harness-run 的执行检查清单。仅在编码执行时读取。
|
|
|
223
223
|
- [ ] 确认当前 cwd 在 `<adapter-worktree-root>/<change-name>/` 下,且 branch 使用 adapter 的 prefix
|
|
224
224
|
- [ ] 生成变更摘要:`git diff --stat` + `git diff --stat --cached`
|
|
225
225
|
- [ ] 构建 commit message:`wip(<scope>): <change-name> 编码完成 — N任务/M文件变更`
|
|
226
|
-
- [ ] **⚠️ 强制阻断**:用
|
|
226
|
+
- [ ] **⚠️ 强制阻断**:用 blocking user confirmation 展示变更列表 + commit message,等待用户确认
|
|
227
227
|
- [ ] 用户确认 → 精确暂存业务文件;若存在 test-tracking manifest,先执行 `harness_test_guard.py stage --project . --change-dir ".harness/changes/<change-name>" --json`;禁止 `git add -A` 与目录级 force-add
|
|
228
228
|
- [ ] `git diff --cached --name-only` 包含 manifest 的全部精确测试路径后再 `git commit`(不用 --no-verify、--no-gpg-sign)
|
|
229
229
|
- [ ] 用户拒绝 → 记录 `❌用户拒绝`,继续后续流程
|
|
@@ -3,7 +3,7 @@ name: harness-submit
|
|
|
3
3
|
description: 最终提交封装:验证→中文 commit→提交/推送;worktree 模式含 --no-ff
|
|
4
4
|
合并回主分支。使用场景:提交代码、commit、push、合并分支、merge to main、完成开发
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=d5b51ad56d4d4535; overlay=none; agent=codebuddy; do not edit -->
|
|
7
7
|
# harness-submit — 最终提交(含 worktree 合并)
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -43,6 +43,7 @@ description: 最终提交封装:验证→中文 commit→提交/推送;workt
|
|
|
43
43
|
9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/knowledge/change/code 指纹,不再重复跑全量 `harness-sync`、知识重建或代码库扫描。只有对应 segment 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
|
|
44
44
|
|
|
45
45
|
状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
|
|
46
|
+
> 片段:read-protocol
|
|
46
47
|
|
|
47
48
|
## 状态目录分层
|
|
48
49
|
|
|
@@ -60,7 +61,7 @@ worktree 合并前必须运行 `harness_change.py integration-lock acquire --run
|
|
|
60
61
|
1. **合并最新代码** — 主目录与 worktree 均**不在业务工作区 stash/pull**;远端同步由合并段 integration transaction 在隔离 integration worktree 内完成(见「worktree 合并流程」);**正常路径禁止 `git stash` / `stash pop`**
|
|
61
62
|
2. **最终验证** — ledger 复用优先;**提交前最终门禁只调 `can-reuse`**(删除与 coverage 冲突的二次全量门禁):`harness_ledger.py can-reuse --verification unitTestFull --scope module --project . --profile-input unitTestFull --command <resolved commands.unitTestFull.command>`。`--command` **按 profile key resolve**:读 `build-profile.json` 的 `commands.unitTestFull.command`(v2),或 `harness_profile.py resolve --project . --key unitTestFull --json` 取 resolved command,**不复制示例模块名**(文档示例只展示 key)。`--profile-input unitTestFull` 从 `verificationInputs.unitTestFull`(v2 由 `commands.unitTestFull.inputs` 派生)展开依赖闭包,**禁止用仅含 staged 文件的 `--files` 快捷方式**冒充全量闭包。`reuse=true` → 不再执行二次全量测试;仅 `reuse=false` 时执行**同一 resolved verification**(profile `unitTestFull` 命令),成功后用同一文件集、command、`scope=module` 经 **`harness_ledger.py record`** 写回 ledger `unitTestFull` 项。增量 `unitTest` 永远不能冒充 `unitTestFull` 门禁。
|
|
62
63
|
3. **.gitignore + 精确暂存** ⚠️ — 检查 `.harness/` 在 `.gitignore`;**禁止 `git add -A`**。若存在 `evidence/test-tracking.json`,先执行 `python <skills-root>/scripts/harness_test_guard.py stage --project . --change-dir ".harness/changes/<change-name>" --json`;失败即硬停止。无 manifest 时不使用 `-f`。manifest 之外的文件按精确业务路径正常暂存,**禁止全局 force-add**。
|
|
63
|
-
4. **提交方式** — 主目录:
|
|
64
|
+
4. **提交方式** — 主目录:blocking user confirmation 三选项(commit+push / 仅本地 / 取消);**worktree:固定仅本地 commit**
|
|
64
65
|
5. **commit-message.txt** ⚠️ — 展示 staged、diff stat、完整中文 message;用户确认
|
|
65
66
|
6. **commit / push** — `git commit -F`;主目录按选项 push(push 前 fetch 检查远端);**worktree:只 commit,记录 local hash**
|
|
66
67
|
7. **收尾** — **`harness_gate.py close --phase submit --status ...`**;主目录:可选 worktree 清理 + 提示 `/harness-archive`;**worktree:接续下方合并流程**
|
|
@@ -89,6 +90,7 @@ M7. **ledger + 收尾** — 经 `harness_ledger.py record` 写入 `mergeFinalHas
|
|
|
89
90
|
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
90
91
|
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
91
92
|
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
93
|
+
> 片段:p0-trust
|
|
92
94
|
|
|
93
95
|
## 关键规则(硬门禁速查)
|
|
94
96
|
|
|
@@ -134,7 +136,7 @@ git 经 PowerShell;commit/报告不得含明文密钥。遵循 `../protocols/s
|
|
|
134
136
|
|
|
135
137
|
## 交互白名单
|
|
136
138
|
|
|
137
|
-
本 skill **仅允许**以下
|
|
139
|
+
本 skill **仅允许**以下 blocking user confirmation;其余默认值 + `decision` 事件:
|
|
138
140
|
|
|
139
141
|
1. **提交方式 + commit message**(主目录一次确认);worktree 固定仅本地 commit,仅确认 message
|
|
140
142
|
2. **远程有新提交**(push 前):重新验证 / 停止 push
|
|
@@ -152,3 +154,4 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
152
154
|
> **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 边界保持最新。
|
|
153
155
|
|
|
154
156
|
每次阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`;重试同一阶段时增加 `--attempt <n>`,不得覆盖或伪装成一次执行。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
157
|
+
> 片段:logging · phase=`submit`/`merge`
|
|
@@ -12,7 +12,7 @@ description: harness-submit 的8 步工作流详细步骤和执行日志记录
|
|
|
12
12
|
- commit message 必须写入 `.harness/changes/<change>/runtime/commit-message.txt`。
|
|
13
13
|
- 使用 `git commit -F`,禁止先英文 commit 再 amend。
|
|
14
14
|
- commit message 禁止 `Co-Authored-By`、`Generated by`、`AI generated`。
|
|
15
|
-
-
|
|
15
|
+
- blocking user confirmation 参数错误时不得自行绕过,必须改用固定模板重问。
|
|
16
16
|
- staged diff 是唯一提交依据。
|
|
17
17
|
|
|
18
18
|
|
|
@@ -130,7 +130,7 @@ powershell.exe -Command "Select-String -Path '<项目路径>\.gitignore' -Patter
|
|
|
130
130
|
|
|
131
131
|
如果未包含:
|
|
132
132
|
- **必须提醒用户**:`⚠️ .gitignore 未包含 .harness/,会导致 .harness/ 下文件被提交(含日志、报告、可能含敏感信息)`
|
|
133
|
-
- **默认不提交 .harness/ 下文件**:使用
|
|
133
|
+
- **默认不提交 .harness/ 下文件**:使用 blocking user confirmation 询问用户是否:
|
|
134
134
|
1. 添加 .harness/ 到 .gitignore(推荐)
|
|
135
135
|
2. 仅 stage 业务代码文件,不提交 .harness/
|
|
136
136
|
3. 取消提交
|
|
@@ -146,7 +146,7 @@ powershell.exe -Command "git -C '<项目路径>' status --porcelain | Select-Str
|
|
|
146
146
|
|
|
147
147
|
**worktree 模式(requested=true)**:固定为「仅本地 commit」,不展示「commit+push」选项;commit 完成后继续下方「worktree 合并流程」,跳过下方三选项询问。
|
|
148
148
|
|
|
149
|
-
`harness-submit` 不调用 Superpowers 呈现合并选项。只允许使用固定
|
|
149
|
+
`harness-submit` 不调用 Superpowers 呈现合并选项。只允许使用固定 blocking user confirmation 模板:
|
|
150
150
|
|
|
151
151
|
```text
|
|
152
152
|
本次变更已完成验证,请选择提交方式:
|
|
@@ -156,7 +156,7 @@ powershell.exe -Command "git -C '<项目路径>' status --porcelain | Select-Str
|
|
|
156
156
|
3. 取消提交
|
|
157
157
|
```
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
禁止在此步骤引入"创建 PR""丢弃所有变更""直接合并到主分支"等旧选项,避免 blocking user confirmation 参数错误和流程歧义。
|
|
160
160
|
|
|
161
161
|
## 步骤 5:展示提交摘要 + 确认 ⚠️ 强制阻断
|
|
162
162
|
|
|
@@ -256,7 +256,7 @@ powershell.exe -Command "git -C '<项目路径>' log HEAD..@{u} --oneline"
|
|
|
256
256
|
- **不得直接 pull 后 push**
|
|
257
257
|
- 必须 pull/rebase 后**重新构建/测试**(ledger 复用条件被破坏,须重跑并写回 ledger)
|
|
258
258
|
- 验证通过后再 push
|
|
259
|
-
- 使用
|
|
259
|
+
- 使用 blocking user confirmation 询问用户:
|
|
260
260
|
```
|
|
261
261
|
远程有新提交(N 个),需要 pull/rebase 后重新验证:
|
|
262
262
|
1. 重新验证(pull/rebase + 构建 + 测试)
|
|
@@ -4,7 +4,7 @@ description: harness-submit 的提交格式、固定交互模板和中文 commit
|
|
|
4
4
|
|
|
5
5
|
# harness-submit 参考
|
|
6
6
|
|
|
7
|
-
## 提交方式
|
|
7
|
+
## 提交方式 blocking user confirmation 固定模板
|
|
8
8
|
|
|
9
9
|
问题标题:`请选择提交方式`
|
|
10
10
|
|
|
@@ -14,7 +14,7 @@ description: harness-submit 的提交格式、固定交互模板和中文 commit
|
|
|
14
14
|
2. `仅本地 commit,不 push`
|
|
15
15
|
3. `取消提交`
|
|
16
16
|
|
|
17
|
-
不得临场增加复杂对象或嵌套参数,避免
|
|
17
|
+
不得临场增加复杂对象或嵌套参数,避免 blocking user confirmation 参数错误。
|
|
18
18
|
|
|
19
19
|
> **worktree 模式(meta/worktree.json requested=true)**:固定选项 2「仅本地 commit」,不展示「commit+push」;commit 成功后 skill **自动接续** worktree 合并流程(`/harness-merge` 为别名)。push 只在主分支完成,产出 `mergeFinalHash`。
|
|
20
20
|
|
|
@@ -148,5 +148,5 @@ powershell.exe -NoProfile -Command "git -C '<项目路径>' log HEAD..@{u} --one
|
|
|
148
148
|
|
|
149
149
|
- 步骤 1(合并最新代码):按无 upstream / 远端无新提交判定 N/A,在执行日志记录理由。
|
|
150
150
|
- 步骤 5(commit-message.txt + `git commit -F`)N/A:无可暂存 diff,无新 commit 需生成。执行日志标注 `commit-message.txt / git commit -F: N/A(工作树 clean,无新 commit;N 个 wip 提交已存在,原样推送)`。
|
|
151
|
-
- 步骤 4(提交方式选择):固定三选项仍适用。但当 review 标了 RED 兼容性破坏等需人工确认项时,可在"commit + push"选项的描述中注明"并确认 <RED 项>",**不得新增第四选项**、不得临场拼复杂
|
|
151
|
+
- 步骤 4(提交方式选择):固定三选项仍适用。但当 review 标了 RED 兼容性破坏等需人工确认项时,可在"commit + push"选项的描述中注明"并确认 <RED 项>",**不得新增第四选项**、不得临场拼复杂 blocking user confirmation 参数。
|
|
152
152
|
- push 仍按步骤 6:fetch 检查远端 → `git push -u`(无 upstream 则新建远端分支)→ 记录 pre-pull hash + final pushed hash。
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: harness-sync
|
|
3
3
|
description: 检查并更新项目AI元数据(CodeGraph索引、harness-codebase-map分析、CLAUDE.md、AGENTS.md、.harness/完整性),确保Claude对代码库的理解与最新代码一致。当用户说'同步/更新索引/刷新元数据/检查一致性'时使用
|
|
4
4
|
---
|
|
5
|
-
<!-- generated by harness_deploy.py; core=
|
|
5
|
+
<!-- generated by harness_deploy.py; core=d5b51ad56d4d4535; overlay=none; agent=codebuddy; do not edit -->
|
|
6
6
|
# harness-sync — 元数据同步
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
@@ -38,7 +38,7 @@ python <skills-root>/scripts/harness_sync.py finalize --project . --run-id <run-
|
|
|
38
38
|
| 3 | `.harness/codebase/map/` 是否过期 → 报告建议 `/harness-codebase-map` |
|
|
39
39
|
| 3.5 | `harness_knowledge.py sync`;可 `sync --update`;失败不得假装可用。**知识闭环主入口**是 `/harness-knowledge-ingest auto`(含 Agent judge),sync 不重复列人工知识待办 |
|
|
40
40
|
| 3.6 | 单次运行 `harness_knowledge.py maintain --project . --drain --json`,有界推进全部 `.harness/knowledge/maintenance-outbox/{pending,failed}`;不得为每个条目重复启动 Python/重建索引(§8.2:archive close 只 enqueue,sync 异步推进 outbox 到 completed/pending-judge) |
|
|
41
|
-
| 4 | CLAUDE.md 完整性/行数 → 超限
|
|
41
|
+
| 4 | CLAUDE.md 完整性/行数 → 超限 blocking user confirmation 瘦身 |
|
|
42
42
|
| 5 | AGENTS.md 与各 Agent 指令入口一致;Claude Code 启用时验证 CLAUDE.md 引用 AGENTS.md,禁止反向循环引用 |
|
|
43
43
|
| 6 | `.harness/` 结构(init 规程 → `reference.md` 第 6 步);已装 skill 新鲜度只经 `hunter-harness refresh --dry-run --json` 的 post-adaptation freshness 判断,禁止 raw build 字节比较 |
|
|
44
44
|
| 7–9 | `项目规则(见 .harness/context-index.json)/`、构建配置、测试目录 — **只提示不自动修复** |
|
|
@@ -50,6 +50,7 @@ python <skills-root>/scripts/harness_sync.py finalize --project . --run-id <run-
|
|
|
50
50
|
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
51
51
|
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
52
52
|
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
53
|
+
> 片段:p0-trust
|
|
53
54
|
|
|
54
55
|
## 关键规则
|
|
55
56
|
|
|
@@ -80,3 +81,4 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
80
81
|
> **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 边界保持最新。
|
|
81
82
|
|
|
82
83
|
每次阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`;重试同一阶段时增加 `--attempt <n>`,不得覆盖或伪装成一次执行。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
84
|
+
> 片段:logging · phase=`sync`;有未归档变更时写入其 change-dir events
|
|
@@ -58,7 +58,7 @@ powershell.exe -Command "git -C '<项目路径>' diff --stat HEAD~5 2>$null"
|
|
|
58
58
|
|
|
59
59
|
**瘦身策略**:如果超过 200 行,不是简单截断——而是把可独立成篇的细节(如完整编码规范、详细架构图)迁移到 `项目规则(见 .harness/context-index.json)/` 下,CLAUDE.md 保留简洁的索引和关键命令。
|
|
60
60
|
|
|
61
|
-
> ⚠️ CLAUDE.md 需要瘦身时,必须用
|
|
61
|
+
> ⚠️ CLAUDE.md 需要瘦身时,必须用 blocking user confirmation 与用户确认拆分方案后再执行。
|
|
62
62
|
|
|
63
63
|
### 5. AGENTS.md 一致性
|
|
64
64
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: harness-test
|
|
3
3
|
description: 测试执行:读取场景表,执行单元测试+API接口测试+数据兼容验证,输出测试报告。当用户说'跑测试/验证/跑用例/接口测试/单元测试'时使用
|
|
4
4
|
---
|
|
5
|
-
<!-- generated by harness_deploy.py; core=
|
|
5
|
+
<!-- generated by harness_deploy.py; core=d5b51ad56d4d4535; overlay=none; agent=codebuddy; do not edit -->
|
|
6
6
|
# harness-test — 测试执行
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
@@ -39,6 +39,7 @@ description: 测试执行:读取场景表,执行单元测试+API接口测试
|
|
|
39
39
|
9. **每个 skill 边界只刷新一次状态快照** — 先运行 `python <skills-root>/scripts/harness_state.py capture --project . --change-dir ".harness/changes/<change-name>" --base <baseCommit> --json`;`changedSegments=[]` 时复用已有 profile/rules/map/knowledge/change/code 指纹,不再重复跑全量 `harness-sync`、知识重建或代码库扫描。只有对应 segment 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
|
|
40
40
|
|
|
41
41
|
状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
|
|
42
|
+
> 片段:read-protocol
|
|
42
43
|
|
|
43
44
|
## Workflow
|
|
44
45
|
|
|
@@ -87,6 +88,7 @@ description: 测试执行:读取场景表,执行单元测试+API接口测试
|
|
|
87
88
|
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
88
89
|
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
89
90
|
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
91
|
+
> 片段:p0-trust
|
|
90
92
|
|
|
91
93
|
## 关键规则(硬门禁速查)
|
|
92
94
|
|
|
@@ -126,11 +128,11 @@ python <skills-root>/scripts/harness_test_guard.py record --project . --change-d
|
|
|
126
128
|
|
|
127
129
|
### 六、服务启动 + 生命周期管理
|
|
128
130
|
|
|
129
|
-
启动等待状态机:0–30s 每 2s 探测、30–120s 每 5s 探测、>120s 读日志判定;遇启动失败特征立即停。**Service Gate**:`harness_service.py ensure` 返回 `action=needs-user-decision`(用户自启服务占端口)时 **才**
|
|
131
|
+
启动等待状态机:0–30s 每 2s 探测、30–120s 每 5s 探测、>120s 读日志判定;遇启动失败特征立即停。**Service Gate**:`harness_service.py ensure` 返回 `action=needs-user-decision`(用户自启服务占端口)时 **才** blocking user confirmation;AI 托管服务或端口空闲则自动继续,不询问。服务指纹(`moduleInputsHash`,来自 CLI `--files` ∪ `serviceStart.inputFiles`)+ `startCommandHash` + `profile` + `overlayPath` + 进程身份任一变化即 restart;**空输入被拒绝**,不生成可复用空指纹。测试结束默认清理 AI 启动的服务。详见 `reference.md`「服务决策门」。
|
|
130
132
|
|
|
131
133
|
### 七、运行时配置叠加(不动 tracked 配置)
|
|
132
134
|
|
|
133
|
-
禁止默认 Edit tracked 应用配置文件。默认运行时配置叠加(ASCII 绝对路径);改 tracked 配置 → 默认拒绝,记 `decision` 事件(不
|
|
135
|
+
禁止默认 Edit tracked 应用配置文件。默认运行时配置叠加(ASCII 绝对路径);改 tracked 配置 → 默认拒绝,记 `decision` 事件(不 blocking user confirmation,报告 🟡 WARN)。详见 `reference.md`。
|
|
134
136
|
|
|
135
137
|
### 八、Token 缓存与复用
|
|
136
138
|
|
|
@@ -162,7 +164,7 @@ python <skills-root>/scripts/harness_test_guard.py record --project . --change-d
|
|
|
162
164
|
|
|
163
165
|
## 交互白名单
|
|
164
166
|
|
|
165
|
-
本 skill **仅允许**以下
|
|
167
|
+
本 skill **仅允许**以下 blocking user confirmation;其余默认值 + `decision` 事件:
|
|
166
168
|
|
|
167
169
|
1. **Service Gate**:仅当 `harness_service.py ensure` 返回 `needs-user-decision`(用户进程占端口)时询问处理方式
|
|
168
170
|
|
|
@@ -179,3 +181,4 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
179
181
|
> **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 边界保持最新。
|
|
180
182
|
|
|
181
183
|
每次阶段结束必须写 `--status OK|WARN|FAIL|BLOCKED`;重试同一阶段时增加 `--attempt <n>`,不得覆盖或伪装成一次执行。跨工具继续执行时写 `--executor-tool <codex|claude-code|codebuddy|cursor>`,并在接棒事件写 `--handoff-from-tool` / `--handoff-reason`;也可由 `HUNTER_HARNESS_TOOL/AGENT/MODEL/RUN_ID` 环境变量统一注入。
|
|
184
|
+
> 片段:logging · phase=`test` · 事件:phase/command/verification/decision/issue/artifact
|
|
@@ -276,7 +276,7 @@ powershell.exe -NoProfile -Command "try { (Invoke-WebRequest -Uri 'http://127.0.
|
|
|
276
276
|
- [ ] **只有首选执行器不可执行才降级**:PowerShell batch (.ps1) → 多次 MCP `browser_evaluate` → curl
|
|
277
277
|
- [ ] **如果执行器在 PowerShell 可用,禁止使用 Playwright MCP 逐条执行接口测试**
|
|
278
278
|
- [ ] 执行器直连本地 baseURL,复用认证凭证,不依赖浏览器 origin
|
|
279
|
-
- [ ] 记录每个请求的
|
|
279
|
+
- [ ] 记录每个请求的 requestDurationMs、status、code、message、assertionResult
|
|
280
280
|
- [ ] 支持失败时继续执行后续非依赖场景
|
|
281
281
|
- [ ] 报告区分四种执行器:**接口测试执行器 / PowerShell batch / Playwright MCP browser_evaluate / curl**(不得与"Playwright"混写)
|
|
282
282
|
|
|
@@ -287,11 +287,14 @@ powershell.exe -NoProfile -Command "try { (Invoke-WebRequest -Uri 'http://127.0.
|
|
|
287
287
|
- [ ] 测试结束后清理可清理的数据
|
|
288
288
|
- [ ] 不能清理的记录遗留数据和原因
|
|
289
289
|
|
|
290
|
-
###
|
|
290
|
+
### 请求耗时(§5.22 分层耗时)
|
|
291
291
|
|
|
292
|
-
- [ ] 每个请求记录
|
|
293
|
-
- [ ]
|
|
294
|
-
- [ ]
|
|
292
|
+
- [ ] 每个请求记录 requestDurationMs(单 HTTP 请求耗时)
|
|
293
|
+
- [ ] 整个批次记录 batchDurationMs(runner wall-clock)
|
|
294
|
+
- [ ] requestDurationMs > 10000 → 🟡SLOW,说明原因
|
|
295
|
+
- [ ] requestDurationMs > 30000 → ❌TIMEOUT_RISK,说明原因
|
|
296
|
+
- [ ] batchDurationMs > 180000 → 🟡BATCH_SLOW
|
|
297
|
+
- [ ] 聚合合同套件场景只记录 batch reference + coveredTests,**禁止均摊生成伪 requestDurationMs**
|
|
295
298
|
|
|
296
299
|
### 覆盖标注诚实性(✅ 实测 vs 🟡 推断)
|
|
297
300
|
|
|
@@ -191,7 +191,7 @@ $cred = $resp.data.accessToken
|
|
|
191
191
|
**严重度**:🟡WARN
|
|
192
192
|
**场景**:测试期间为了切换外部服务配置直接 Edit tracked 配置文件(如 `application-local-dev.yml`),测试后再还原,留下 diff 噪声
|
|
193
193
|
**后果**:git diff --stat 出现意外文件、提交风险、误以为有业务变更
|
|
194
|
-
**正确做法**:生成运行时配置叠加 `.harness/changes/<change>/runtime/application-harness-test.yml`(不提交),启动用 `-Dspring.config.additional-location=file:...` 叠加(按技术栈);如必须改 tracked 配置,先
|
|
194
|
+
**正确做法**:生成运行时配置叠加 `.harness/changes/<change>/runtime/application-harness-test.yml`(不提交),启动用 `-Dspring.config.additional-location=file:...` 叠加(按技术栈);如必须改 tracked 配置,先 blocking user confirmation,最终报告至少 🟡 WARN
|
|
195
195
|
|
|
196
196
|
### 规则 22:唯一约束字段与本地预存数据冲突
|
|
197
197
|
**严重度**:❌FAIL
|
|
@@ -150,7 +150,7 @@ spring:
|
|
|
150
150
|
powershell.exe -NoProfile -Command "mvn spring-boot:run -pl <module> -Dspring-boot.run.profiles=<profile> -Dspring-boot.run.jvmArguments='-Dspring.config.additional-location=file:C:/temp/harness-test-overlay/<change-name>/application-harness-test.yml'"
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
不得默认使用 `.harness/changes/<change>/runtime/application-harness-test.yml` 相对路径作为 JVM `additional-location`。如必须修改 tracked 配置文件,先
|
|
153
|
+
不得默认使用 `.harness/changes/<change>/runtime/application-harness-test.yml` 相对路径作为 JVM `additional-location`。如必须修改 tracked 配置文件,先 blocking user confirmation,最终报告至少 🟡 WARN。
|
|
154
154
|
|
|
155
155
|
## 服务决策门(Service Decision Gate)与服务生命周期管理
|
|
156
156
|
|
|
@@ -361,11 +361,13 @@ async function cleanup(token) {
|
|
|
361
361
|
|
|
362
362
|
// ===== 主流程 =====
|
|
363
363
|
const token = await resolveCredential('admin');
|
|
364
|
+
const batchStart = Date.now();
|
|
364
365
|
await setup(token);
|
|
365
366
|
for (const scenario of scenarios) {
|
|
366
367
|
await runOne(scenario, token);
|
|
367
368
|
}
|
|
368
369
|
const cleanupResult = await cleanup(token);
|
|
370
|
+
const batchDurationMs = Date.now() - batchStart;
|
|
369
371
|
|
|
370
372
|
const summary = {
|
|
371
373
|
runner: 'api-test-executor',
|
|
@@ -377,7 +379,11 @@ const summary = {
|
|
|
377
379
|
setupErrors: setupState.errors,
|
|
378
380
|
cleanupResult,
|
|
379
381
|
credentialRefreshCount,
|
|
380
|
-
|
|
382
|
+
// §5.22: 分层耗时 schema — batchDurationMs 是整个 runner wall-clock;
|
|
383
|
+
// 每个场景的 requestDurationMs 是单 HTTP 请求耗时。聚合合同套件场景
|
|
384
|
+
// 只记录 batch reference/coveredTests,不允许均摊生成伪请求耗时。
|
|
385
|
+
batchDurationMs,
|
|
386
|
+
startedAt: '<ISO>', finishedAt: '<ISO>'
|
|
381
387
|
};
|
|
382
388
|
writeFileSync(RESULTS_FILE, JSON.stringify({ results, summary }, null, 2));
|
|
383
389
|
console.log(`\n结果已写入 ${RESULTS_FILE}`);
|
|
@@ -389,6 +395,7 @@ console.log(`\n结果已写入 ${RESULTS_FILE}`);
|
|
|
389
395
|
> - 凭证从本地 cache 读 + 本地轻量接口验证,**完全不依赖浏览器当前页面 origin**
|
|
390
396
|
> - 同一次执行内 `credentialRefreshCount` 不得 > 1
|
|
391
397
|
> - payload 从数据契约/接口定义/真实样例生成,并在脚本注释中标注字段来源
|
|
398
|
+
> - **§5.22 分层耗时**:`batchDurationMs` 是 runner wall-clock(整个批次耗时),`requestDurationMs` 是单 HTTP 请求耗时。聚合合同套件场景(如 API-C01~C04 共享同一 pytest 批次)只记录 `batchReference` + `coveredTests`,**禁止用 `batchDurationMs / N` 均摊生成伪 `requestDurationMs`**
|
|
392
399
|
|
|
393
400
|
### 执行器降级方案(PowerShell batch runner .ps1)
|
|
394
401
|
|
|
@@ -445,18 +452,20 @@ $results | ConvertTo-Json -Depth 4
|
|
|
445
452
|
| 接口测试执行器(普通) | 30s | **60s** | 抛错继续报告,不再重试 |
|
|
446
453
|
| 接口测试执行器(复杂场景) | 60s | **120s** | 同上 |
|
|
447
454
|
| 凭证获取(认证服务) | 5–10s | **15s** | 计 1 次重取;超过 1 次 → 🟡 WARN |
|
|
448
|
-
| 单个 HTTP GET | < 1s | **8s** |
|
|
449
|
-
| 单个 HTTP POST/PUT | < 2s | **10s** |
|
|
455
|
+
| 单个 HTTP GET | < 1s | **8s** | requestDurationMs > 10s → 🟡 SLOW |
|
|
456
|
+
| 单个 HTTP POST/PUT | < 2s | **10s** | requestDurationMs > 10s → 🟡 SLOW |
|
|
450
457
|
| health probe | < 1s | **3s** | 计入启动状态机 |
|
|
451
458
|
| 构建工具编译(如 Maven compile) | 10–60s | **180s** | 输出最后 30 行日志后停 |
|
|
452
459
|
| 测试命令(如 Maven test) | 60–180s | **300s** | 输出失败用例后停 |
|
|
453
460
|
| service start | 30–60s | **120s** | 4.1 启动状态机收敛 |
|
|
454
461
|
|
|
455
|
-
|
|
462
|
+
**§5.22 分层耗时与反馈规则**:
|
|
456
463
|
- 等待 > 10s 必须输出一次状态行(启动等待、执行器、构建工具均适用)
|
|
457
464
|
- 不得静默等待
|
|
458
|
-
-
|
|
459
|
-
-
|
|
465
|
+
- **`requestDurationMs`**(单 HTTP 请求耗时):`> 10000` → 🟡 SLOW;`> 30000` → ❌ TIMEOUT_RISK
|
|
466
|
+
- **`batchDurationMs`**(runner wall-clock,整个批次耗时):`> 180000`(3 分钟)→ 🟡 BATCH_SLOW;`> 300000`(5 分钟)→ ❌ BATCH_TIMEOUT_RISK
|
|
467
|
+
- **聚合合同套件场景**(如 API-C01~C04 共享同一 pytest 批次):只记录 `batchReference` + `coveredTests`,**禁止用 `batchDurationMs / N` 均摊生成伪 `requestDurationMs`**
|
|
468
|
+
- 报告必须明确标注是哪一层越界(batch-level 还是 request-level),不得混用
|
|
460
469
|
- 请求慢不得忽略,必须说明是服务、网络、认证还是工具调用开销
|
|
461
470
|
|
|
462
471
|
## 认证凭证缓存与复用
|
|
@@ -638,17 +647,23 @@ TEST_<change-name>_<timestamp>_<short-random>
|
|
|
638
647
|
| cleanup | cleaned=X / leftover=Y | 接口 /<resource> 不支持删除,2 条遗留 |
|
|
639
648
|
|
|
640
649
|
### 接口测试
|
|
641
|
-
| # | 场景 | 方法 | URL | 预期 | 实际 |
|
|
650
|
+
| # | 场景 | 方法 | URL | 预期 | 实际 | requestDurationMs | 状态 |
|
|
642
651
|
|:--:|------|:----:|-----|------|------|----------:|:--:|
|
|
643
652
|
| API-001 | 创建资源 | POST | /api/xxx | 200, code=0 | 200, code=0 | 245 | ✅ PASS |
|
|
644
653
|
| API-002 | 参数校验 | POST | /api/xxx | code=xxx | code=xxx | 180 | ✅ PASS |
|
|
645
654
|
| API-003 | 查询子规则 | GET | /api/xxx/{id} | 200 | — | — | 🟡 BLOCKED(setup.createRule 失败) |
|
|
646
655
|
|
|
647
|
-
###
|
|
648
|
-
|
|
|
649
|
-
|
|
650
|
-
| API-001 | POST | /api/xxx |
|
|
651
|
-
| API-010 | GET | /api/yyy |
|
|
656
|
+
### 请求耗时统计(§5.22 分层耗时)
|
|
657
|
+
| 层级 | 场景/批次 | 方法 | URL | 耗时 | 状态 |
|
|
658
|
+
|------|----------|:----:|-----|----:|:----:|
|
|
659
|
+
| request | API-001 | POST | /api/xxx | 245ms | ✅ |
|
|
660
|
+
| request | API-010 | GET | /api/yyy | 12450ms | 🟡SLOW |
|
|
661
|
+
| batch | pytest-batch-1 | — | — | 158000ms | 🟡BATCH_SLOW |
|
|
662
|
+
|
|
663
|
+
> **§5.22 分层耗时说明**:
|
|
664
|
+
> - `request` 层级记录单 HTTP 请求耗时(`requestDurationMs`)
|
|
665
|
+
> - `batch` 层级记录 runner wall-clock(`batchDurationMs`),整个 pytest 批次耗时
|
|
666
|
+
> - 聚合合同套件场景(如 API-C01~C04 共享同一批次)只记录一行 `batch` 条目 + `coveredTests` 列表,**不得均摊为 4 个伪 `request` 条目**
|
|
652
667
|
|
|
653
668
|
### 数据兼容
|
|
654
669
|
| # | 场景 | 预期 | 实际 | 结果 |
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: harness-submit 的确定性提交协议。用于避免
|
|
2
|
+
description: harness-submit 的确定性提交协议。用于避免 blocking user confirmation 参数错误、中文 commit message 失败、Co-Authored-By 违规和先 commit 后 amend。
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Submit Protocol
|
|
@@ -26,6 +26,10 @@ if hasattr(sys.stderr, "reconfigure"):
|
|
|
26
26
|
sys.stderr.reconfigure(encoding="utf-8")
|
|
27
27
|
|
|
28
28
|
INCLUDE_RE = re.compile(r"<!--\s*@include\s+shared/([^\s]+)\s*-->")
|
|
29
|
+
# retro §5.17: wiki links [[shared/xxx.md|alias]] reference shared fragments
|
|
30
|
+
# that are inlined by expand_includes. After expansion, replace the wiki link
|
|
31
|
+
# with the alias text (the shared content is already in the document).
|
|
32
|
+
WIKI_LINK_RE = re.compile(r"\[\[shared/([^\]|]+)\|([^\]]*)\]\]")
|
|
29
33
|
# §7.5: overlay anchors support both new section-id and legacy section:"title".
|
|
30
34
|
OVERRIDE_RE = re.compile(r'<!--\s*@override\s+(?:section-id:"([^"]+)"|section:"([^"]+)")\s*-->')
|
|
31
35
|
APPEND_RE = re.compile(r'<!--\s*@append-after\s+(?:section-id:"([^"]+)"|section:"([^"]+)")\s*-->')
|
|
@@ -148,6 +152,9 @@ def expand_includes(text: str, shared_dir: Path) -> str:
|
|
|
148
152
|
return body
|
|
149
153
|
|
|
150
154
|
expanded = INCLUDE_RE.sub(repl, text)
|
|
155
|
+
# §5.17: replace [[shared/xxx.md|alias]] wiki links with the alias text,
|
|
156
|
+
# since the shared content has been inlined by @include expansion above.
|
|
157
|
+
expanded = WIKI_LINK_RE.sub(lambda m: m.group(2), expanded)
|
|
151
158
|
lines = [ln for ln in expanded.splitlines() if not FRAGMENT_HINT_RE.match(ln)]
|
|
152
159
|
return "\n".join(lines) + ("\n" if text.endswith("\n") else "")
|
|
153
160
|
|
|
@@ -1201,6 +1201,70 @@ def _phase_event_exists(change_dir: Path, phase: str, type_: str, run_id: str) -
|
|
|
1201
1201
|
)
|
|
1202
1202
|
|
|
1203
1203
|
|
|
1204
|
+
def _validate_scenario_coverage(change_dir: Path) -> dict[str, Any]:
|
|
1205
|
+
"""C9: validate all P0 scenarios have a ledger entry with scenarioIds covering them.
|
|
1206
|
+
|
|
1207
|
+
Reads meta/scenario-manifest.json and evidence/verification-ledger.json.
|
|
1208
|
+
Returns ok=True when manifest missing (backward compat) or all P0 scenarios covered.
|
|
1209
|
+
"""
|
|
1210
|
+
manifest_path = change_dir / "meta" / "scenario-manifest.json"
|
|
1211
|
+
if not manifest_path.is_file():
|
|
1212
|
+
return {"ok": True, "code": "MANIFEST_MISSING", "skipped": True}
|
|
1213
|
+
try:
|
|
1214
|
+
manifest = json.loads(manifest_path.read_text(encoding="utf-8-sig"))
|
|
1215
|
+
except (OSError, json.JSONDecodeError) as exc:
|
|
1216
|
+
return {
|
|
1217
|
+
"ok": False,
|
|
1218
|
+
"code": "SCENARIO_MANIFEST_INVALID",
|
|
1219
|
+
"message": f"scenario-manifest.json unreadable: {exc}",
|
|
1220
|
+
}
|
|
1221
|
+
scenarios = manifest.get("scenarios") or []
|
|
1222
|
+
p0_ids = {
|
|
1223
|
+
str(s.get("id"))
|
|
1224
|
+
for s in scenarios
|
|
1225
|
+
if isinstance(s, dict)
|
|
1226
|
+
and str(s.get("priority", "")).upper() == "P0"
|
|
1227
|
+
and s.get("requiredEvidenceKind") == "ledger"
|
|
1228
|
+
}
|
|
1229
|
+
if not p0_ids:
|
|
1230
|
+
return {"ok": True, "code": "NO_P0_SCENARIOS"}
|
|
1231
|
+
|
|
1232
|
+
ledger_path = change_dir / "evidence" / "verification-ledger.json"
|
|
1233
|
+
if not ledger_path.is_file():
|
|
1234
|
+
return {
|
|
1235
|
+
"ok": False,
|
|
1236
|
+
"code": "SCENARIO_COVERAGE_FAILED",
|
|
1237
|
+
"message": "ledger missing; cannot verify P0 scenario coverage",
|
|
1238
|
+
"missing": sorted(p0_ids),
|
|
1239
|
+
}
|
|
1240
|
+
try:
|
|
1241
|
+
ledger = json.loads(ledger_path.read_text(encoding="utf-8-sig"))
|
|
1242
|
+
except (OSError, json.JSONDecodeError) as exc:
|
|
1243
|
+
return {
|
|
1244
|
+
"ok": False,
|
|
1245
|
+
"code": "SCENARIO_COVERAGE_FAILED",
|
|
1246
|
+
"message": f"ledger unreadable: {exc}",
|
|
1247
|
+
"missing": sorted(p0_ids),
|
|
1248
|
+
}
|
|
1249
|
+
covered: set[str] = set()
|
|
1250
|
+
validations = ledger.get("validations") or {}
|
|
1251
|
+
if isinstance(validations, dict):
|
|
1252
|
+
for entry in validations.values():
|
|
1253
|
+
if isinstance(entry, dict):
|
|
1254
|
+
ids = entry.get("scenarioIds")
|
|
1255
|
+
if isinstance(ids, list):
|
|
1256
|
+
covered.update(str(i) for i in ids)
|
|
1257
|
+
missing = sorted(p0_ids - covered)
|
|
1258
|
+
if missing:
|
|
1259
|
+
return {
|
|
1260
|
+
"ok": False,
|
|
1261
|
+
"code": "SCENARIO_COVERAGE_FAILED",
|
|
1262
|
+
"message": f"P0 scenarios without ledger entry: {', '.join(missing)}",
|
|
1263
|
+
"missing": missing,
|
|
1264
|
+
}
|
|
1265
|
+
return {"ok": True, "code": "SCENARIO_COVERAGE_OK", "covered": sorted(covered & p0_ids)}
|
|
1266
|
+
|
|
1267
|
+
|
|
1204
1268
|
def cmd_begin(args: argparse.Namespace) -> int:
|
|
1205
1269
|
as_json = bool(args.json)
|
|
1206
1270
|
project = hc.resolve_main_project_root()
|
|
@@ -1470,6 +1534,17 @@ def cmd_close(args: argparse.Namespace) -> int:
|
|
|
1470
1534
|
extra={k: v for k, v in ledger_result.items() if k not in {"ok", "message", "code"}},
|
|
1471
1535
|
)
|
|
1472
1536
|
|
|
1537
|
+
# C9: scenario coverage check — all P0 scenarios must have a ledger entry.
|
|
1538
|
+
if args.phase in {"run", "test"}:
|
|
1539
|
+
coverage = _validate_scenario_coverage(change_dir)
|
|
1540
|
+
if not coverage.get("ok"):
|
|
1541
|
+
return emit_error(
|
|
1542
|
+
str(coverage.get("code", "SCENARIO_COVERAGE_FAILED")),
|
|
1543
|
+
str(coverage.get("message", "scenario coverage validation failed")),
|
|
1544
|
+
as_json=as_json,
|
|
1545
|
+
extra={k: v for k, v in coverage.items() if k not in {"ok", "message", "code"}},
|
|
1546
|
+
)
|
|
1547
|
+
|
|
1473
1548
|
close_status = args.status
|
|
1474
1549
|
close_code = "PHASE_CLOSED"
|
|
1475
1550
|
if ledger_result.get("code") == "LEDGER_OK_DEGRADED":
|
|
@@ -1049,10 +1049,11 @@ class IntegrationTransaction:
|
|
|
1049
1049
|
heavy_removed.append(name)
|
|
1050
1050
|
except OSError as exc:
|
|
1051
1051
|
heavy_failures.append({"path": name, "error": str(exc)})
|
|
1052
|
-
self.runner.run(
|
|
1052
|
+
remove_result = self.runner.run(
|
|
1053
1053
|
self.project_root, "worktree", "remove", "--force", str(resolved),
|
|
1054
1054
|
check=False,
|
|
1055
1055
|
)
|
|
1056
|
+
remove_returncode = getattr(remove_result, "returncode", 0)
|
|
1056
1057
|
listed = self.runner.text(self.project_root, "worktree", "list", "--porcelain")
|
|
1057
1058
|
registered_after = {
|
|
1058
1059
|
str(Path(line.removeprefix("worktree ")).resolve())
|
|
@@ -1061,7 +1062,8 @@ class IntegrationTransaction:
|
|
|
1061
1062
|
}
|
|
1062
1063
|
still_registered = str(resolved) in registered_after
|
|
1063
1064
|
residual_paths: list[str] = []
|
|
1064
|
-
|
|
1065
|
+
disk_path_present = resolved.exists()
|
|
1066
|
+
if disk_path_present:
|
|
1065
1067
|
if resolved.is_file():
|
|
1066
1068
|
residual_paths.append(resolved.name)
|
|
1067
1069
|
else:
|
|
@@ -1075,6 +1077,27 @@ class IntegrationTransaction:
|
|
|
1075
1077
|
break
|
|
1076
1078
|
if len(residual_paths) >= 200:
|
|
1077
1079
|
break
|
|
1080
|
+
# §5.30: Windows half-success — git worktree remove returned non-zero
|
|
1081
|
+
# but registration is already deleted and disk path remains. Return a
|
|
1082
|
+
# structured status distinct from generic CLEANUP_RESIDUAL so callers
|
|
1083
|
+
# can apply the allowlisted residual cleaner.
|
|
1084
|
+
if (
|
|
1085
|
+
remove_returncode != 0
|
|
1086
|
+
and not still_registered
|
|
1087
|
+
and disk_path_present
|
|
1088
|
+
and residual_paths
|
|
1089
|
+
and not heavy_failures
|
|
1090
|
+
):
|
|
1091
|
+
return {
|
|
1092
|
+
"ok": False,
|
|
1093
|
+
"code": "REGISTRATION_REMOVED_RESIDUAL_PRESENT",
|
|
1094
|
+
"target": str(resolved),
|
|
1095
|
+
"heavyRootsRemoved": heavy_removed,
|
|
1096
|
+
"heavyRootFailures": heavy_failures,
|
|
1097
|
+
"worktreeRegistered": False,
|
|
1098
|
+
"diskPathPresent": True,
|
|
1099
|
+
"residualPaths": residual_paths,
|
|
1100
|
+
}
|
|
1078
1101
|
ok = not heavy_failures and not still_registered and not residual_paths
|
|
1079
1102
|
return {
|
|
1080
1103
|
"ok": ok,
|
|
@@ -1083,6 +1106,7 @@ class IntegrationTransaction:
|
|
|
1083
1106
|
"heavyRootsRemoved": heavy_removed,
|
|
1084
1107
|
"heavyRootFailures": heavy_failures,
|
|
1085
1108
|
"worktreeRegistered": still_registered,
|
|
1109
|
+
"diskPathPresent": disk_path_present,
|
|
1086
1110
|
"residualPaths": residual_paths,
|
|
1087
1111
|
}
|
|
1088
1112
|
|
|
@@ -1266,6 +1290,31 @@ def cmd_status(args: argparse.Namespace) -> int:
|
|
|
1266
1290
|
return _emit(_txn_from_args(args).status())
|
|
1267
1291
|
|
|
1268
1292
|
|
|
1293
|
+
def cmd_journal(args: argparse.Namespace) -> int:
|
|
1294
|
+
"""C5: journal 子命令 — 默认 compact (transactionId/currentStep/status),--verbose 全量。"""
|
|
1295
|
+
txn = _txn_from_args(args)
|
|
1296
|
+
full = txn.status()
|
|
1297
|
+
if getattr(args, "verbose", False):
|
|
1298
|
+
return _emit(full)
|
|
1299
|
+
# Derive currentStep: first non-DONE step, or last step name if all DONE.
|
|
1300
|
+
current_step = None
|
|
1301
|
+
for step in full.get("steps", []):
|
|
1302
|
+
if step.get("status") != "DONE":
|
|
1303
|
+
current_step = step.get("name")
|
|
1304
|
+
break
|
|
1305
|
+
if current_step is None and full.get("steps"):
|
|
1306
|
+
current_step = full["steps"][-1].get("name")
|
|
1307
|
+
overall_status = "DONE" if all(
|
|
1308
|
+
step.get("status") == "DONE" for step in full.get("steps", [])
|
|
1309
|
+
) else "IN_PROGRESS"
|
|
1310
|
+
compact = {
|
|
1311
|
+
"transactionId": full.get("transactionId"),
|
|
1312
|
+
"currentStep": current_step,
|
|
1313
|
+
"status": overall_status,
|
|
1314
|
+
}
|
|
1315
|
+
return _emit(compact)
|
|
1316
|
+
|
|
1317
|
+
|
|
1269
1318
|
def build_parser() -> argparse.ArgumentParser:
|
|
1270
1319
|
parser = argparse.ArgumentParser(prog="harness_integration.py")
|
|
1271
1320
|
sub = parser.add_subparsers(dest="command_name", required=True)
|
|
@@ -1287,6 +1336,19 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1287
1336
|
add("recover", cmd_recover)
|
|
1288
1337
|
add("status", cmd_status)
|
|
1289
1338
|
|
|
1339
|
+
p_journal = sub.add_parser("journal")
|
|
1340
|
+
p_journal.add_argument("--change", required=True)
|
|
1341
|
+
p_journal.add_argument("--run-id", required=True)
|
|
1342
|
+
p_journal.add_argument("--target-branch", default="main")
|
|
1343
|
+
p_journal.add_argument("--feature-branch", required=True)
|
|
1344
|
+
p_journal.add_argument("--temp-root", required=True)
|
|
1345
|
+
p_journal.add_argument(
|
|
1346
|
+
"--verbose",
|
|
1347
|
+
action="store_true",
|
|
1348
|
+
help="emit full journal payload (default: compact transactionId/currentStep/status)",
|
|
1349
|
+
)
|
|
1350
|
+
p_journal.set_defaults(func=cmd_journal)
|
|
1351
|
+
|
|
1290
1352
|
p_verify = sub.add_parser("verify")
|
|
1291
1353
|
p_verify.add_argument("--change", required=True)
|
|
1292
1354
|
p_verify.add_argument("--run-id", required=True)
|