@hunter-harness/workflow-harness 0.4.3 → 0.4.9
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 +1 -1
- package/harness/bundles/general/claude-code/README.md +36 -38
- package/harness/bundles/general/claude-code/contracts/workflow-policy.json +0 -50
- package/harness/bundles/general/claude-code/harness-archive/SKILL.md +4 -3
- package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/general/claude-code/harness-execute/SKILL.md +19 -17
- package/harness/bundles/general/{codex/harness-run/checklist.md → claude-code/harness-execute/coding-checklist.md} +9 -9
- package/harness/bundles/general/{codex/harness-run/reference.md → claude-code/harness-execute/coding-reference.md} +36 -36
- package/harness/bundles/general/{codex/harness-run → claude-code/harness-execute}/protocols.md +4 -4
- package/harness/bundles/general/{codebuddy/harness-test/checklist.md → claude-code/harness-execute/testing-checklist.md} +9 -10
- package/harness/bundles/general/claude-code/{harness-test/pitfalls-java.md → harness-execute/testing-pitfalls-java.md} +2 -2
- package/harness/bundles/general/{codex/harness-test/pitfalls.md → claude-code/harness-execute/testing-pitfalls.md} +7 -7
- package/harness/bundles/general/claude-code/{harness-test/reference.md → harness-execute/testing-reference.md} +13 -13
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/claude-code/harness-plan/checklist.md +1 -1
- package/harness/bundles/general/claude-code/harness-plan/reference.md +30 -3
- package/harness/bundles/general/claude-code/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-review/SKILL.md +5 -5
- package/harness/bundles/general/claude-code/harness-review/checklist.md +1 -1
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +2 -2
- package/harness/bundles/general/claude-code/harness-submit/checklist.md +1 -1
- package/harness/bundles/general/claude-code/harness-submit/reference.md +1 -1
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +2 -2
- package/harness/bundles/general/claude-code/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/general/claude-code/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/general/claude-code/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/general/claude-code/scripts/harness_archive.py +28 -1
- package/harness/bundles/general/claude-code/scripts/harness_change.py +74 -0
- package/harness/bundles/general/claude-code/scripts/harness_context.py +271 -10
- package/harness/bundles/general/claude-code/scripts/harness_deploy.py +2 -2
- package/harness/bundles/general/claude-code/scripts/harness_events.py +4 -1
- package/harness/bundles/general/claude-code/scripts/harness_gate.py +281 -77
- package/harness/bundles/general/claude-code/scripts/harness_profile.py +3 -3
- package/harness/bundles/general/claude-code/scripts/harness_review.py +120 -0
- package/harness/bundles/general/claude-code/scripts/harness_runtime.py +13 -0
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/CONTEXT.md +1 -1
- package/harness/bundles/general/codebuddy/README.md +36 -38
- package/harness/bundles/general/codebuddy/contracts/workflow-policy.json +0 -50
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +4 -3
- package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/general/codebuddy/harness-execute/SKILL.md +19 -17
- package/harness/bundles/general/{claude-code/harness-run/checklist.md → codebuddy/harness-execute/coding-checklist.md} +9 -9
- package/harness/bundles/general/codebuddy/{harness-run/reference.md → harness-execute/coding-reference.md} +36 -36
- package/harness/bundles/general/codebuddy/{harness-run → harness-execute}/protocols.md +4 -4
- package/harness/bundles/general/{codex/harness-test/checklist.md → codebuddy/harness-execute/testing-checklist.md} +9 -10
- package/harness/bundles/general/codebuddy/{harness-test/pitfalls-java.md → harness-execute/testing-pitfalls-java.md} +2 -2
- package/harness/bundles/general/{claude-code/harness-test/pitfalls.md → codebuddy/harness-execute/testing-pitfalls.md} +7 -7
- package/harness/bundles/general/codebuddy/{harness-test/reference.md → harness-execute/testing-reference.md} +13 -13
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/codebuddy/harness-plan/checklist.md +1 -1
- package/harness/bundles/general/codebuddy/harness-plan/reference.md +30 -3
- package/harness/bundles/general/codebuddy/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-review/SKILL.md +5 -5
- package/harness/bundles/general/codebuddy/harness-review/checklist.md +1 -1
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +2 -2
- package/harness/bundles/general/codebuddy/harness-submit/checklist.md +1 -1
- package/harness/bundles/general/codebuddy/harness-submit/reference.md +1 -1
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +2 -2
- package/harness/bundles/general/codebuddy/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/general/codebuddy/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/general/codebuddy/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/general/codebuddy/scripts/harness_archive.py +28 -1
- package/harness/bundles/general/codebuddy/scripts/harness_change.py +74 -0
- package/harness/bundles/general/codebuddy/scripts/harness_context.py +271 -10
- package/harness/bundles/general/codebuddy/scripts/harness_deploy.py +2 -2
- package/harness/bundles/general/codebuddy/scripts/harness_events.py +4 -1
- package/harness/bundles/general/codebuddy/scripts/harness_gate.py +281 -77
- package/harness/bundles/general/codebuddy/scripts/harness_profile.py +3 -3
- package/harness/bundles/general/codebuddy/scripts/harness_review.py +120 -0
- package/harness/bundles/general/codebuddy/scripts/harness_runtime.py +13 -0
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/CONTEXT.md +1 -1
- package/harness/bundles/general/codex/README.md +36 -38
- package/harness/bundles/general/codex/contracts/workflow-policy.json +0 -50
- package/harness/bundles/general/codex/harness-archive/SKILL.md +4 -3
- package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/general/codex/harness-execute/SKILL.md +19 -17
- package/harness/bundles/general/{cursor/harness-run/checklist.md → codex/harness-execute/coding-checklist.md} +9 -9
- package/harness/bundles/general/{cursor/harness-run/reference.md → codex/harness-execute/coding-reference.md} +36 -36
- package/harness/bundles/general/{claude-code/harness-run → codex/harness-execute}/protocols.md +4 -4
- package/harness/bundles/general/{cursor/harness-test/checklist.md → codex/harness-execute/testing-checklist.md} +9 -10
- package/harness/bundles/general/codex/{harness-test/pitfalls-java.md → harness-execute/testing-pitfalls-java.md} +2 -2
- package/harness/bundles/general/{codebuddy/harness-test/pitfalls.md → codex/harness-execute/testing-pitfalls.md} +7 -7
- package/harness/bundles/general/codex/{harness-test/reference.md → harness-execute/testing-reference.md} +13 -13
- package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/codex/harness-plan/checklist.md +1 -1
- package/harness/bundles/general/codex/harness-plan/reference.md +30 -3
- package/harness/bundles/general/codex/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-review/SKILL.md +3 -3
- package/harness/bundles/general/codex/harness-review/checklist.md +1 -1
- package/harness/bundles/general/codex/harness-submit/SKILL.md +2 -2
- package/harness/bundles/general/codex/harness-submit/checklist.md +1 -1
- package/harness/bundles/general/codex/harness-submit/reference.md +1 -1
- package/harness/bundles/general/codex/harness-sync/SKILL.md +2 -2
- package/harness/bundles/general/codex/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/general/codex/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/general/codex/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/general/codex/scripts/harness_archive.py +28 -1
- package/harness/bundles/general/codex/scripts/harness_change.py +74 -0
- package/harness/bundles/general/codex/scripts/harness_context.py +271 -10
- package/harness/bundles/general/codex/scripts/harness_deploy.py +2 -2
- package/harness/bundles/general/codex/scripts/harness_events.py +4 -1
- package/harness/bundles/general/codex/scripts/harness_gate.py +281 -77
- package/harness/bundles/general/codex/scripts/harness_profile.py +3 -3
- package/harness/bundles/general/codex/scripts/harness_review.py +120 -0
- package/harness/bundles/general/codex/scripts/harness_runtime.py +13 -0
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/CONTEXT.md +1 -1
- package/harness/bundles/general/cursor/README.md +36 -38
- package/harness/bundles/general/cursor/contracts/workflow-policy.json +0 -50
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +4 -3
- package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/general/cursor/harness-execute/SKILL.md +19 -17
- package/harness/bundles/general/{codebuddy/harness-run/checklist.md → cursor/harness-execute/coding-checklist.md} +9 -9
- package/harness/bundles/general/{claude-code/harness-run/reference.md → cursor/harness-execute/coding-reference.md} +36 -36
- package/harness/bundles/general/cursor/{harness-run → harness-execute}/protocols.md +4 -4
- package/harness/bundles/general/{claude-code/harness-test/checklist.md → cursor/harness-execute/testing-checklist.md} +9 -10
- package/harness/bundles/general/cursor/{harness-test/pitfalls-java.md → harness-execute/testing-pitfalls-java.md} +2 -2
- package/harness/bundles/general/cursor/{harness-test/pitfalls.md → harness-execute/testing-pitfalls.md} +7 -7
- package/harness/bundles/general/cursor/{harness-test/reference.md → harness-execute/testing-reference.md} +13 -13
- package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/cursor/harness-plan/checklist.md +1 -1
- package/harness/bundles/general/cursor/harness-plan/reference.md +30 -3
- package/harness/bundles/general/cursor/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-review/SKILL.md +3 -3
- package/harness/bundles/general/cursor/harness-review/checklist.md +1 -1
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +2 -2
- package/harness/bundles/general/cursor/harness-submit/checklist.md +1 -1
- package/harness/bundles/general/cursor/harness-submit/reference.md +1 -1
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +2 -2
- package/harness/bundles/general/cursor/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/general/cursor/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/general/cursor/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/general/cursor/scripts/harness_archive.py +28 -1
- package/harness/bundles/general/cursor/scripts/harness_change.py +74 -0
- package/harness/bundles/general/cursor/scripts/harness_context.py +271 -10
- package/harness/bundles/general/cursor/scripts/harness_deploy.py +2 -2
- package/harness/bundles/general/cursor/scripts/harness_events.py +4 -1
- package/harness/bundles/general/cursor/scripts/harness_gate.py +281 -77
- package/harness/bundles/general/cursor/scripts/harness_profile.py +3 -3
- package/harness/bundles/general/cursor/scripts/harness_review.py +120 -0
- package/harness/bundles/general/cursor/scripts/harness_runtime.py +13 -0
- package/harness/bundles/general/pi/.harness-build.json +1 -1
- package/harness/bundles/general/pi/CONTEXT.md +1 -1
- package/harness/bundles/general/pi/README.md +36 -38
- package/harness/bundles/general/pi/contracts/workflow-policy.json +0 -50
- package/harness/bundles/general/pi/harness-archive/SKILL.md +4 -3
- package/harness/bundles/general/pi/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/pi/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/general/pi/harness-execute/SKILL.md +19 -17
- package/harness/bundles/general/pi/harness-execute/coding-checklist.md +279 -0
- package/harness/bundles/general/pi/harness-execute/coding-reference.md +886 -0
- package/harness/bundles/general/pi/harness-execute/protocols.md +141 -0
- package/harness/bundles/general/pi/harness-execute/testing-checklist.md +358 -0
- package/harness/bundles/general/pi/harness-execute/testing-pitfalls-java.md +14 -0
- package/harness/bundles/general/pi/harness-execute/testing-pitfalls.md +307 -0
- package/harness/bundles/general/pi/harness-execute/testing-reference.md +880 -0
- package/harness/bundles/general/pi/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/pi/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/pi/harness-plan/SKILL.md +2 -2
- package/harness/bundles/general/pi/harness-plan/checklist.md +1 -1
- package/harness/bundles/general/pi/harness-plan/reference.md +30 -3
- package/harness/bundles/general/pi/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/pi/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/pi/harness-review/SKILL.md +3 -3
- package/harness/bundles/general/pi/harness-review/checklist.md +1 -1
- package/harness/bundles/general/pi/harness-submit/SKILL.md +2 -2
- package/harness/bundles/general/pi/harness-submit/checklist.md +1 -1
- package/harness/bundles/general/pi/harness-submit/reference.md +1 -1
- package/harness/bundles/general/pi/harness-sync/SKILL.md +2 -2
- package/harness/bundles/general/pi/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/general/pi/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/general/pi/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/general/pi/scripts/harness_archive.py +28 -1
- package/harness/bundles/general/pi/scripts/harness_change.py +74 -0
- package/harness/bundles/general/pi/scripts/harness_context.py +271 -10
- package/harness/bundles/general/pi/scripts/harness_deploy.py +2 -2
- package/harness/bundles/general/pi/scripts/harness_events.py +4 -1
- package/harness/bundles/general/pi/scripts/harness_gate.py +281 -77
- package/harness/bundles/general/pi/scripts/harness_profile.py +3 -3
- package/harness/bundles/general/pi/scripts/harness_review.py +120 -0
- package/harness/bundles/general/pi/scripts/harness_runtime.py +13 -0
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/CONTEXT.md +1 -1
- package/harness/bundles/java/claude-code/README.md +36 -38
- package/harness/bundles/java/claude-code/contracts/workflow-policy.json +0 -50
- package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-archive/SKILL.md +4 -3
- package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/java/claude-code/harness-execute/SKILL.md +51 -17
- package/harness/bundles/java/claude-code/{harness-run/checklist.md → harness-execute/coding-checklist.md} +6 -6
- package/harness/bundles/java/claude-code/{harness-run/reference.md → harness-execute/coding-reference.md} +37 -37
- package/harness/bundles/java/claude-code/harness-execute/protocols.md +141 -0
- package/harness/bundles/java/claude-code/{harness-test/checklist.md → harness-execute/testing-checklist.md} +9 -9
- package/harness/bundles/java/claude-code/{harness-test/pitfalls-java.md → harness-execute/testing-pitfalls-java.md} +1 -1
- package/harness/bundles/java/claude-code/harness-execute/testing-pitfalls.md +307 -0
- package/harness/bundles/java/claude-code/{harness-test/reference.md → harness-execute/testing-reference.md} +13 -13
- 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-package/checklist.md +7 -7
- package/harness/bundles/java/claude-code/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/claude-code/harness-plan/checklist.md +1 -1
- package/harness/bundles/java/claude-code/harness-plan/reference.md +30 -3
- package/harness/bundles/java/claude-code/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-review/SKILL.md +5 -5
- package/harness/bundles/java/claude-code/harness-review/checklist.md +1 -1
- package/harness/bundles/java/claude-code/harness-submit/SKILL.md +2 -2
- package/harness/bundles/java/claude-code/harness-submit/checklist.md +1 -1
- package/harness/bundles/java/claude-code/harness-submit/reference.md +1 -1
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +2 -2
- package/harness/bundles/java/claude-code/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/java/claude-code/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/java/claude-code/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/java/claude-code/scripts/harness_archive.py +28 -1
- package/harness/bundles/java/claude-code/scripts/harness_change.py +74 -0
- package/harness/bundles/java/claude-code/scripts/harness_context.py +271 -10
- package/harness/bundles/java/claude-code/scripts/harness_deploy.py +2 -2
- package/harness/bundles/java/claude-code/scripts/harness_events.py +4 -1
- package/harness/bundles/java/claude-code/scripts/harness_gate.py +281 -77
- package/harness/bundles/java/claude-code/scripts/harness_profile.py +3 -3
- package/harness/bundles/java/claude-code/scripts/harness_review.py +120 -0
- package/harness/bundles/java/claude-code/scripts/harness_runtime.py +13 -0
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/CONTEXT.md +1 -1
- package/harness/bundles/java/codebuddy/README.md +36 -38
- package/harness/bundles/java/codebuddy/contracts/workflow-policy.json +0 -50
- package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +4 -3
- package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/java/codebuddy/harness-execute/SKILL.md +51 -17
- package/harness/bundles/java/codebuddy/{harness-run/checklist.md → harness-execute/coding-checklist.md} +6 -6
- package/harness/bundles/java/codebuddy/{harness-run/reference.md → harness-execute/coding-reference.md} +37 -37
- package/harness/bundles/java/codebuddy/harness-execute/protocols.md +141 -0
- package/harness/bundles/java/codebuddy/{harness-test/checklist.md → harness-execute/testing-checklist.md} +9 -9
- package/harness/bundles/java/codebuddy/{harness-test/pitfalls-java.md → harness-execute/testing-pitfalls-java.md} +1 -1
- package/harness/bundles/java/codebuddy/harness-execute/testing-pitfalls.md +307 -0
- package/harness/bundles/java/codebuddy/{harness-test/reference.md → harness-execute/testing-reference.md} +13 -13
- 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-package/checklist.md +7 -7
- package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/codebuddy/harness-plan/checklist.md +1 -1
- package/harness/bundles/java/codebuddy/harness-plan/reference.md +30 -3
- package/harness/bundles/java/codebuddy/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-review/SKILL.md +5 -5
- package/harness/bundles/java/codebuddy/harness-review/checklist.md +1 -1
- package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +2 -2
- package/harness/bundles/java/codebuddy/harness-submit/checklist.md +1 -1
- package/harness/bundles/java/codebuddy/harness-submit/reference.md +1 -1
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +2 -2
- package/harness/bundles/java/codebuddy/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/java/codebuddy/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/java/codebuddy/scripts/harness_archive.py +28 -1
- package/harness/bundles/java/codebuddy/scripts/harness_change.py +74 -0
- package/harness/bundles/java/codebuddy/scripts/harness_context.py +271 -10
- package/harness/bundles/java/codebuddy/scripts/harness_deploy.py +2 -2
- package/harness/bundles/java/codebuddy/scripts/harness_events.py +4 -1
- package/harness/bundles/java/codebuddy/scripts/harness_gate.py +281 -77
- package/harness/bundles/java/codebuddy/scripts/harness_profile.py +3 -3
- package/harness/bundles/java/codebuddy/scripts/harness_review.py +120 -0
- package/harness/bundles/java/codebuddy/scripts/harness_runtime.py +13 -0
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/CONTEXT.md +1 -1
- package/harness/bundles/java/codex/README.md +36 -38
- package/harness/bundles/java/codex/contracts/workflow-policy.json +0 -50
- package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-archive/SKILL.md +4 -3
- package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/java/codex/harness-execute/SKILL.md +51 -17
- package/harness/bundles/java/codex/{harness-run/checklist.md → harness-execute/coding-checklist.md} +6 -6
- package/harness/bundles/java/codex/{harness-run/reference.md → harness-execute/coding-reference.md} +37 -37
- package/harness/bundles/java/codex/harness-execute/protocols.md +141 -0
- package/harness/bundles/java/codex/{harness-test/checklist.md → harness-execute/testing-checklist.md} +9 -9
- package/harness/bundles/java/codex/{harness-test/pitfalls-java.md → harness-execute/testing-pitfalls-java.md} +1 -1
- package/harness/bundles/java/codex/harness-execute/testing-pitfalls.md +307 -0
- package/harness/bundles/java/codex/{harness-test/reference.md → harness-execute/testing-reference.md} +13 -13
- 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-package/checklist.md +7 -7
- package/harness/bundles/java/codex/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/codex/harness-plan/checklist.md +1 -1
- package/harness/bundles/java/codex/harness-plan/reference.md +30 -3
- package/harness/bundles/java/codex/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-review/SKILL.md +3 -3
- package/harness/bundles/java/codex/harness-review/checklist.md +1 -1
- package/harness/bundles/java/codex/harness-submit/SKILL.md +2 -2
- package/harness/bundles/java/codex/harness-submit/checklist.md +1 -1
- package/harness/bundles/java/codex/harness-submit/reference.md +1 -1
- package/harness/bundles/java/codex/harness-sync/SKILL.md +2 -2
- package/harness/bundles/java/codex/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/java/codex/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/java/codex/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/java/codex/scripts/harness_archive.py +28 -1
- package/harness/bundles/java/codex/scripts/harness_change.py +74 -0
- package/harness/bundles/java/codex/scripts/harness_context.py +271 -10
- package/harness/bundles/java/codex/scripts/harness_deploy.py +2 -2
- package/harness/bundles/java/codex/scripts/harness_events.py +4 -1
- package/harness/bundles/java/codex/scripts/harness_gate.py +281 -77
- package/harness/bundles/java/codex/scripts/harness_profile.py +3 -3
- package/harness/bundles/java/codex/scripts/harness_review.py +120 -0
- package/harness/bundles/java/codex/scripts/harness_runtime.py +13 -0
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/CONTEXT.md +1 -1
- package/harness/bundles/java/cursor/README.md +36 -38
- package/harness/bundles/java/cursor/contracts/workflow-policy.json +0 -50
- package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-archive/SKILL.md +4 -3
- package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/java/cursor/harness-execute/SKILL.md +51 -17
- package/harness/bundles/java/cursor/{harness-run/checklist.md → harness-execute/coding-checklist.md} +6 -6
- package/harness/bundles/java/cursor/{harness-run/reference.md → harness-execute/coding-reference.md} +37 -37
- package/harness/bundles/java/cursor/harness-execute/protocols.md +141 -0
- package/harness/bundles/java/cursor/{harness-test/checklist.md → harness-execute/testing-checklist.md} +9 -9
- package/harness/bundles/java/cursor/{harness-test/pitfalls-java.md → harness-execute/testing-pitfalls-java.md} +1 -1
- package/harness/bundles/java/cursor/harness-execute/testing-pitfalls.md +307 -0
- package/harness/bundles/java/cursor/{harness-test/reference.md → harness-execute/testing-reference.md} +13 -13
- 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-package/checklist.md +7 -7
- package/harness/bundles/java/cursor/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/cursor/harness-plan/checklist.md +1 -1
- package/harness/bundles/java/cursor/harness-plan/reference.md +30 -3
- package/harness/bundles/java/cursor/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-review/SKILL.md +3 -3
- package/harness/bundles/java/cursor/harness-review/checklist.md +1 -1
- package/harness/bundles/java/cursor/harness-submit/SKILL.md +2 -2
- package/harness/bundles/java/cursor/harness-submit/checklist.md +1 -1
- package/harness/bundles/java/cursor/harness-submit/reference.md +1 -1
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +2 -2
- package/harness/bundles/java/cursor/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/java/cursor/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/java/cursor/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/java/cursor/scripts/harness_archive.py +28 -1
- package/harness/bundles/java/cursor/scripts/harness_change.py +74 -0
- package/harness/bundles/java/cursor/scripts/harness_context.py +271 -10
- package/harness/bundles/java/cursor/scripts/harness_deploy.py +2 -2
- package/harness/bundles/java/cursor/scripts/harness_events.py +4 -1
- package/harness/bundles/java/cursor/scripts/harness_gate.py +281 -77
- package/harness/bundles/java/cursor/scripts/harness_profile.py +3 -3
- package/harness/bundles/java/cursor/scripts/harness_review.py +120 -0
- package/harness/bundles/java/cursor/scripts/harness_runtime.py +13 -0
- package/harness/bundles/java/pi/.harness-build.json +1 -1
- package/harness/bundles/java/pi/CONTEXT.md +1 -1
- package/harness/bundles/java/pi/README.md +36 -38
- package/harness/bundles/java/pi/contracts/workflow-policy.json +0 -50
- package/harness/bundles/java/pi/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/pi/harness-archive/SKILL.md +4 -3
- package/harness/bundles/java/pi/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/pi/harness-codebase-map/templates/TESTING.md +1 -1
- package/harness/bundles/java/pi/harness-execute/SKILL.md +51 -17
- package/harness/bundles/java/pi/harness-execute/coding-checklist.md +252 -0
- package/harness/bundles/java/pi/harness-execute/coding-reference.md +820 -0
- package/harness/bundles/java/pi/harness-execute/protocols.md +141 -0
- package/harness/bundles/java/pi/harness-execute/testing-checklist.md +320 -0
- package/harness/bundles/java/pi/harness-execute/testing-pitfalls-java.md +16 -0
- package/harness/bundles/java/pi/harness-execute/testing-pitfalls.md +307 -0
- package/harness/bundles/java/pi/harness-execute/testing-reference.md +792 -0
- package/harness/bundles/java/pi/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/pi/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/pi/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/pi/harness-package/checklist.md +7 -7
- package/harness/bundles/java/pi/harness-plan/SKILL.md +2 -2
- package/harness/bundles/java/pi/harness-plan/checklist.md +1 -1
- package/harness/bundles/java/pi/harness-plan/reference.md +30 -3
- package/harness/bundles/java/pi/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/pi/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/pi/harness-review/SKILL.md +3 -3
- package/harness/bundles/java/pi/harness-review/checklist.md +1 -1
- package/harness/bundles/java/pi/harness-submit/SKILL.md +2 -2
- package/harness/bundles/java/pi/harness-submit/checklist.md +1 -1
- package/harness/bundles/java/pi/harness-submit/reference.md +1 -1
- package/harness/bundles/java/pi/harness-sync/SKILL.md +2 -2
- package/harness/bundles/java/pi/protocols/evidence-based-reporting-protocol.md +1 -1
- package/harness/bundles/java/pi/protocols/ledger-protocol.md +8 -8
- package/harness/bundles/java/pi/protocols/sensitive-info-protocol.md +2 -2
- package/harness/bundles/java/pi/scripts/harness_archive.py +28 -1
- package/harness/bundles/java/pi/scripts/harness_change.py +74 -0
- package/harness/bundles/java/pi/scripts/harness_context.py +271 -10
- package/harness/bundles/java/pi/scripts/harness_deploy.py +2 -2
- package/harness/bundles/java/pi/scripts/harness_events.py +4 -1
- package/harness/bundles/java/pi/scripts/harness_gate.py +281 -77
- package/harness/bundles/java/pi/scripts/harness_profile.py +3 -3
- package/harness/bundles/java/pi/scripts/harness_review.py +120 -0
- package/harness/bundles/java/pi/scripts/harness_runtime.py +13 -0
- package/harness/manifests/general/claude-code.json +65 -73
- package/harness/manifests/general/codebuddy.json +65 -73
- package/harness/manifests/general/codex.json +65 -73
- package/harness/manifests/general/cursor.json +65 -73
- package/harness/manifests/general/pi.json +65 -73
- package/harness/manifests/java/claude-code.json +68 -76
- package/harness/manifests/java/codebuddy.json +68 -76
- package/harness/manifests/java/codex.json +68 -76
- package/harness/manifests/java/cursor.json +68 -76
- package/harness/manifests/java/pi.json +68 -76
- package/hunter-workflow-family.json +2 -2
- package/package.json +15 -15
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +0 -207
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +0 -270
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +0 -188
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +0 -250
- package/harness/bundles/general/codex/harness-run/SKILL.md +0 -188
- package/harness/bundles/general/codex/harness-test/SKILL.md +0 -250
- package/harness/bundles/general/cursor/harness-run/SKILL.md +0 -188
- package/harness/bundles/general/cursor/harness-test/SKILL.md +0 -250
- package/harness/bundles/general/pi/harness-run/SKILL.md +0 -188
- package/harness/bundles/general/pi/harness-run/checklist.md +0 -279
- package/harness/bundles/general/pi/harness-run/protocols.md +0 -141
- package/harness/bundles/general/pi/harness-run/reference.md +0 -886
- package/harness/bundles/general/pi/harness-test/SKILL.md +0 -250
- package/harness/bundles/general/pi/harness-test/checklist.md +0 -359
- package/harness/bundles/general/pi/harness-test/pitfalls-java.md +0 -14
- package/harness/bundles/general/pi/harness-test/pitfalls.md +0 -307
- package/harness/bundles/general/pi/harness-test/reference.md +0 -880
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +0 -225
- package/harness/bundles/java/claude-code/harness-run/protocols.md +0 -141
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +0 -284
- package/harness/bundles/java/claude-code/harness-test/pitfalls.md +0 -307
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +0 -206
- package/harness/bundles/java/codebuddy/harness-run/protocols.md +0 -141
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +0 -264
- package/harness/bundles/java/codebuddy/harness-test/pitfalls.md +0 -307
- package/harness/bundles/java/codex/harness-run/SKILL.md +0 -206
- package/harness/bundles/java/codex/harness-run/protocols.md +0 -141
- package/harness/bundles/java/codex/harness-test/SKILL.md +0 -264
- package/harness/bundles/java/codex/harness-test/pitfalls.md +0 -307
- package/harness/bundles/java/cursor/harness-run/SKILL.md +0 -206
- package/harness/bundles/java/cursor/harness-run/protocols.md +0 -141
- package/harness/bundles/java/cursor/harness-test/SKILL.md +0 -264
- package/harness/bundles/java/cursor/harness-test/pitfalls.md +0 -307
- package/harness/bundles/java/pi/harness-run/SKILL.md +0 -206
- package/harness/bundles/java/pi/harness-run/checklist.md +0 -252
- package/harness/bundles/java/pi/harness-run/protocols.md +0 -141
- package/harness/bundles/java/pi/harness-run/reference.md +0 -820
- package/harness/bundles/java/pi/harness-test/SKILL.md +0 -264
- package/harness/bundles/java/pi/harness-test/checklist.md +0 -320
- package/harness/bundles/java/pi/harness-test/pitfalls-java.md +0 -16
- package/harness/bundles/java/pi/harness-test/pitfalls.md +0 -307
- package/harness/bundles/java/pi/harness-test/reference.md +0 -792
- /package/harness/bundles/general/claude-code/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/general/codebuddy/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/general/codex/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/general/cursor/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/general/pi/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/java/claude-code/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/java/codebuddy/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/java/codex/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/java/cursor/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
- /package/harness/bundles/java/pi/{harness-test → harness-execute}/scripts/runtime-helpers.mjs +0 -0
|
@@ -121,6 +121,11 @@ def emit_error(
|
|
|
121
121
|
sys.stderr.write(json.dumps(payload, ensure_ascii=False) + "\n")
|
|
122
122
|
else:
|
|
123
123
|
sys.stderr.write(f"error: {message} ({code})\n")
|
|
124
|
+
# 文本模式同样给出恢复指引——--json 的 recoveryAction 一直有,
|
|
125
|
+
# 但人类读的恰恰是文本模式(2026-08-30 实测:用户翻文档才找到 claim 命令)
|
|
126
|
+
recovery = payload.get("recoveryAction")
|
|
127
|
+
if isinstance(recovery, str) and recovery:
|
|
128
|
+
sys.stderr.write(f"recovery: {recovery}\n")
|
|
124
129
|
return 1
|
|
125
130
|
|
|
126
131
|
|
|
@@ -1967,12 +1972,20 @@ def validate_context_for_gate_begin(
|
|
|
1967
1972
|
return {"ok": True, "code": "CONTEXT_LEGACY_COMPATIBLE"}
|
|
1968
1973
|
current_phase = str(current.get("phase") or view.get("currentPhase") or "")
|
|
1969
1974
|
if hp.resolve_phase_name(current_phase) != phase:
|
|
1975
|
+
candidates = hctx.allowed_next_phases(project, change_id, current_phase)
|
|
1970
1976
|
return {
|
|
1971
1977
|
"ok": False,
|
|
1972
1978
|
"code": "CONTEXT_HANDOFF_REQUIRED",
|
|
1973
1979
|
"message": "阶段交接尚未完成,门禁未启动;请先完成上下文交接。",
|
|
1974
1980
|
"expectedPhase": current_phase or None,
|
|
1975
1981
|
"requestedPhase": phase,
|
|
1982
|
+
"recoveryAction": (
|
|
1983
|
+
f"当前上下文停留在 {current_phase} 阶段。一条命令补齐交接"
|
|
1984
|
+
"(自动补租约→写收据→begin 确认,无需 change claim/release):"
|
|
1985
|
+
f"harness_context.py handoff --project . --change {change_id} "
|
|
1986
|
+
f"--to-phase {phase} --executor <tool> --json"
|
|
1987
|
+
+ (f"(计划后继阶段:{'/'.join(candidates)})" if candidates else "")
|
|
1988
|
+
),
|
|
1976
1989
|
}
|
|
1977
1990
|
if isinstance(transitions, list) and transitions:
|
|
1978
1991
|
latest = transitions[-1] if isinstance(transitions[-1], dict) else {}
|
|
@@ -1990,6 +2003,12 @@ def validate_context_for_gate_begin(
|
|
|
1990
2003
|
"code": "CONTEXT_BEGIN_REQUIRED",
|
|
1991
2004
|
"message": "阶段交接收据尚未确认,门禁未启动;请先执行上下文 begin。",
|
|
1992
2005
|
"requestedPhase": phase,
|
|
2006
|
+
"recoveryAction": (
|
|
2007
|
+
"交接收据已写入但缺 begin 确认。一条命令补齐:"
|
|
2008
|
+
f"harness_context.py handoff --project . --change {change_id} "
|
|
2009
|
+
f"--to-phase {phase} --executor <tool> --json"
|
|
2010
|
+
"(检测到收据已存在时只补 begin 确认,不写重复 receipt)"
|
|
2011
|
+
),
|
|
1993
2012
|
}
|
|
1994
2013
|
return {"ok": True, "code": "CONTEXT_READY"}
|
|
1995
2014
|
|
|
@@ -2201,7 +2220,7 @@ def _validate_scenario_coverage(
|
|
|
2201
2220
|
is due by that phase are required to carry passing receipts. Scenarios
|
|
2202
2221
|
owned by a later phase (e.g. `ownerPhase=test` at `run` close) are
|
|
2203
2222
|
reported under `deferred` instead of blocking the close — this matches the
|
|
2204
|
-
documented hand-off rule in harness-
|
|
2223
|
+
documented hand-off rule in harness-execute/SKILL.md ("ownerPhase=test 按计划移交").
|
|
2205
2224
|
"""
|
|
2206
2225
|
manifest_path = change_dir / "meta" / "scenario-manifest.json"
|
|
2207
2226
|
if not manifest_path.is_file():
|
|
@@ -2503,7 +2522,11 @@ def validate_review_outputs_for_close(
|
|
|
2503
2522
|
"code": "REVIEW_OUTPUTS_INCOMPLETE",
|
|
2504
2523
|
"message": "评审的结构化发现或处置记录缺失,尚不能结束评审阶段。",
|
|
2505
2524
|
"missing": missing,
|
|
2506
|
-
"recoveryAction":
|
|
2525
|
+
"recoveryAction": (
|
|
2526
|
+
"用骨架生成器补写:harness_review.py scaffold --change-dir <change-dir>"
|
|
2527
|
+
"(无 findings 时先生成发现骨架→write-findings 落地→重跑 scaffold "
|
|
2528
|
+
"生成处置骨架→write-dispositions 落地),再重试关门"
|
|
2529
|
+
),
|
|
2507
2530
|
}
|
|
2508
2531
|
try:
|
|
2509
2532
|
findings = json.loads(findings_path.read_text(encoding="utf-8-sig"))
|
|
@@ -2930,6 +2953,169 @@ def cmd_begin(args: argparse.Namespace) -> int:
|
|
|
2930
2953
|
return 0
|
|
2931
2954
|
|
|
2932
2955
|
|
|
2956
|
+
def _emit_close_summary(
|
|
2957
|
+
code: str,
|
|
2958
|
+
phase: str,
|
|
2959
|
+
status: str,
|
|
2960
|
+
to_phase: str | None,
|
|
2961
|
+
*,
|
|
2962
|
+
derived: bool = False,
|
|
2963
|
+
) -> None:
|
|
2964
|
+
"""关门成功的一行摘要(stderr,不污染 stdout 的 JSON 契约)。"""
|
|
2965
|
+
suffix = "(auto)" if derived and to_phase else ""
|
|
2966
|
+
sys.stderr.write(
|
|
2967
|
+
f"{code} · phase={phase} · status={status} · next={to_phase or '-'}{suffix}\n"
|
|
2968
|
+
)
|
|
2969
|
+
|
|
2970
|
+
|
|
2971
|
+
def _finalize_close_journal(
|
|
2972
|
+
change_dir: Path,
|
|
2973
|
+
phase: str,
|
|
2974
|
+
run_id: str,
|
|
2975
|
+
close_status: str,
|
|
2976
|
+
) -> None:
|
|
2977
|
+
"""续跑成功后把 capsule 的 closeTransaction 收口为 CLOSED(best-effort)。"""
|
|
2978
|
+
if not run_id:
|
|
2979
|
+
return
|
|
2980
|
+
try:
|
|
2981
|
+
capsule = load_phase_capsule(change_dir, phase, run_id)
|
|
2982
|
+
except (OSError, ValueError):
|
|
2983
|
+
capsule = None
|
|
2984
|
+
if not isinstance(capsule, dict):
|
|
2985
|
+
return
|
|
2986
|
+
transaction = capsule.get("closeTransaction")
|
|
2987
|
+
if not isinstance(transaction, dict):
|
|
2988
|
+
return
|
|
2989
|
+
transaction.update({
|
|
2990
|
+
"status": "CLOSED",
|
|
2991
|
+
"retryable": False,
|
|
2992
|
+
"leaseReleased": True,
|
|
2993
|
+
"updatedAt": he.now_iso(),
|
|
2994
|
+
})
|
|
2995
|
+
capsule["closedAt"] = he.now_iso()
|
|
2996
|
+
capsule["closeStatus"] = close_status
|
|
2997
|
+
try:
|
|
2998
|
+
write_phase_capsule(change_dir, phase, run_id, capsule)
|
|
2999
|
+
except OSError:
|
|
3000
|
+
pass
|
|
3001
|
+
|
|
3002
|
+
|
|
3003
|
+
def _resume_closed_phase(
|
|
3004
|
+
project: Path,
|
|
3005
|
+
resolved: dict[str, Any],
|
|
3006
|
+
args: argparse.Namespace,
|
|
3007
|
+
terminal: dict[str, Any],
|
|
3008
|
+
*,
|
|
3009
|
+
as_json: bool,
|
|
3010
|
+
) -> int:
|
|
3011
|
+
"""phase.end 已写、租约已释放、收尾未走完的幂等续跑。
|
|
3012
|
+
|
|
3013
|
+
这个中间态是"租约释放早于后续步骤"(或输出中断)留下的:本地关门事实
|
|
3014
|
+
已经存在,剩下的 handoff/monitor/recovery/scratch 全部幂等。识别并补跑,
|
|
3015
|
+
而不是报 LEASE_ABSENT 逼调用方手工 claim 重取租约(2026-08-30 实测路径)。
|
|
3016
|
+
"""
|
|
3017
|
+
change_id = str(resolved["changeId"])
|
|
3018
|
+
change_dir = Path(resolved["changeDir"])
|
|
3019
|
+
run_id = str(terminal.get("run_id") or getattr(args, "run_id", None) or "")
|
|
3020
|
+
close_status = str(terminal.get("status") or args.status)
|
|
3021
|
+
to_phase = getattr(args, "to_phase", None)
|
|
3022
|
+
|
|
3023
|
+
view = hctx.context_view(project, change_id)
|
|
3024
|
+
transitions = view.get("transitions") if isinstance(view, dict) else None
|
|
3025
|
+
handoff_recorded = isinstance(transitions, list) and any(
|
|
3026
|
+
isinstance(item, dict)
|
|
3027
|
+
and hp.resolve_phase_name(item.get("fromPhase")) == args.phase
|
|
3028
|
+
for item in transitions
|
|
3029
|
+
)
|
|
3030
|
+
|
|
3031
|
+
handoff: dict[str, Any] | None = None
|
|
3032
|
+
derived_to_phase: str | None = None
|
|
3033
|
+
if handoff_recorded:
|
|
3034
|
+
# 交接收据已在 transitions.ndjson——重放 close_transition 也只会幂等命中
|
|
3035
|
+
handoff = {"ok": True, "code": "TRANSITION_ALREADY_CLOSED", "resumed": True}
|
|
3036
|
+
else:
|
|
3037
|
+
candidates = [
|
|
3038
|
+
candidate
|
|
3039
|
+
for candidate in hctx.allowed_next_phases(project, change_id, args.phase)
|
|
3040
|
+
if hp.resolve_phase_name(candidate) != args.phase
|
|
3041
|
+
]
|
|
3042
|
+
if to_phase is None and len(candidates) == 1:
|
|
3043
|
+
# 计划后继唯一(排除 fixback 自环):close 的意图没有歧义,直接补跑 handoff
|
|
3044
|
+
to_phase = candidates[0]
|
|
3045
|
+
args.to_phase = to_phase
|
|
3046
|
+
derived_to_phase = to_phase
|
|
3047
|
+
if to_phase is None and candidates:
|
|
3048
|
+
return emit_error(
|
|
3049
|
+
"PHASE_HANDOFF_PENDING",
|
|
3050
|
+
"phase gate already closed locally (phase.end recorded), but the context "
|
|
3051
|
+
"handoff is still pending and the successor is ambiguous; re-run with --to-phase",
|
|
3052
|
+
as_json=as_json,
|
|
3053
|
+
extra={
|
|
3054
|
+
"localCloseComplete": True,
|
|
3055
|
+
"retryable": True,
|
|
3056
|
+
"phase": args.phase,
|
|
3057
|
+
"status": close_status,
|
|
3058
|
+
"changeId": change_id,
|
|
3059
|
+
"candidateNextPhases": candidates,
|
|
3060
|
+
"recoveryAction": (
|
|
3061
|
+
"本地关门已完成(phase.end 已写、租约已释放),只剩上下文交接。"
|
|
3062
|
+
"不需要重新 claim 租约——用原命令补 --to-phase 重跑即幂等续跑:"
|
|
3063
|
+
"python <skills-root>/scripts/harness_gate.py close "
|
|
3064
|
+
f"--phase {args.phase} --change {change_id} --status {close_status} "
|
|
3065
|
+
f"--to-phase <{'|'.join(candidates)}> --json"
|
|
3066
|
+
),
|
|
3067
|
+
},
|
|
3068
|
+
)
|
|
3069
|
+
if to_phase is not None:
|
|
3070
|
+
handoff = _close_context_handoff(
|
|
3071
|
+
project,
|
|
3072
|
+
change_id,
|
|
3073
|
+
args,
|
|
3074
|
+
status=close_status,
|
|
3075
|
+
)
|
|
3076
|
+
monitor = _sync_after_phase_close(project, change_dir)
|
|
3077
|
+
if isinstance(handoff, dict) and not handoff.get("ok"):
|
|
3078
|
+
return emit_error(
|
|
3079
|
+
"PHASE_HANDOFF_PENDING",
|
|
3080
|
+
"phase gate is closed, but context handoff still needs attention",
|
|
3081
|
+
as_json=as_json,
|
|
3082
|
+
extra={
|
|
3083
|
+
"localCloseComplete": True,
|
|
3084
|
+
"retryable": True,
|
|
3085
|
+
"contextHandoff": handoff,
|
|
3086
|
+
"platformMonitor": monitor,
|
|
3087
|
+
},
|
|
3088
|
+
)
|
|
3089
|
+
recovery_result = record_gate_recovered(
|
|
3090
|
+
change_dir,
|
|
3091
|
+
phase=args.phase,
|
|
3092
|
+
run_id=run_id,
|
|
3093
|
+
)
|
|
3094
|
+
try:
|
|
3095
|
+
scratch_swept = hruntime.sweep_scratch(change_dir)
|
|
3096
|
+
except Exception as exc: # noqa: BLE001 — 收尾步骤失败只记录,绝不阻断续跑
|
|
3097
|
+
scratch_swept = {"ok": False, "code": "SCRATCH_SWEEP_FAILED", "error": str(exc)}
|
|
3098
|
+
_finalize_close_journal(change_dir, args.phase, run_id, close_status)
|
|
3099
|
+
emit(
|
|
3100
|
+
{
|
|
3101
|
+
"ok": True,
|
|
3102
|
+
"code": "PHASE_CLOSE_RESUMED",
|
|
3103
|
+
"phase": args.phase,
|
|
3104
|
+
"status": close_status,
|
|
3105
|
+
"changeId": change_id,
|
|
3106
|
+
"localCloseComplete": True,
|
|
3107
|
+
"contextHandoff": handoff,
|
|
3108
|
+
"platformMonitor": monitor,
|
|
3109
|
+
"gateRecovery": recovery_result,
|
|
3110
|
+
"scratchSwept": scratch_swept,
|
|
3111
|
+
**({"derivedToPhase": derived_to_phase} if derived_to_phase else {}),
|
|
3112
|
+
},
|
|
3113
|
+
as_json=as_json,
|
|
3114
|
+
)
|
|
3115
|
+
_emit_close_summary("PHASE_CLOSE_RESUMED", args.phase, close_status, to_phase, derived=derived_to_phase is not None)
|
|
3116
|
+
return 0
|
|
3117
|
+
|
|
3118
|
+
|
|
2933
3119
|
def cmd_close(args: argparse.Namespace) -> int:
|
|
2934
3120
|
as_json = bool(args.json)
|
|
2935
3121
|
normalized = _normalize_gate_phase(args, as_json)
|
|
@@ -3043,47 +3229,13 @@ def cmd_close(args: argparse.Namespace) -> int:
|
|
|
3043
3229
|
|
|
3044
3230
|
if current_lease is None:
|
|
3045
3231
|
terminal = _latest_phase_end(change_dir, args.phase, explicit_run_id)
|
|
3046
|
-
if (
|
|
3047
|
-
|
|
3048
|
-
and terminal is not None
|
|
3049
|
-
and _terminal_matches_context_session(
|
|
3050
|
-
project, str(resolved["changeId"]), args.phase, terminal
|
|
3051
|
-
)
|
|
3232
|
+
if terminal is not None and _terminal_matches_context_session(
|
|
3233
|
+
project, str(resolved["changeId"]), args.phase, terminal
|
|
3052
3234
|
):
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
args,
|
|
3058
|
-
status=terminal_status,
|
|
3059
|
-
)
|
|
3060
|
-
monitor = _sync_after_phase_close(project, change_dir)
|
|
3061
|
-
if not isinstance(handoff, dict) or not handoff.get("ok"):
|
|
3062
|
-
return emit_error(
|
|
3063
|
-
"PHASE_HANDOFF_PENDING",
|
|
3064
|
-
"phase gate is closed, but context handoff still needs attention",
|
|
3065
|
-
as_json=as_json,
|
|
3066
|
-
extra={
|
|
3067
|
-
"localCloseComplete": True,
|
|
3068
|
-
"retryable": True,
|
|
3069
|
-
"contextHandoff": handoff,
|
|
3070
|
-
"platformMonitor": monitor,
|
|
3071
|
-
},
|
|
3072
|
-
)
|
|
3073
|
-
emit(
|
|
3074
|
-
{
|
|
3075
|
-
"ok": True,
|
|
3076
|
-
"code": "PHASE_CLOSE_RESUMED",
|
|
3077
|
-
"phase": args.phase,
|
|
3078
|
-
"status": terminal_status,
|
|
3079
|
-
"changeId": resolved["changeId"],
|
|
3080
|
-
"localCloseComplete": True,
|
|
3081
|
-
"contextHandoff": handoff,
|
|
3082
|
-
"platformMonitor": monitor,
|
|
3083
|
-
},
|
|
3084
|
-
as_json=as_json,
|
|
3085
|
-
)
|
|
3086
|
-
return 0
|
|
3235
|
+
# phase.end 已写且属于当前会话:本地关门已完成,租约缺失是历史运行的
|
|
3236
|
+
# 释放顺序(或输出中断)留下的中间态——幂等续跑剩余步骤,与是否携带
|
|
3237
|
+
# --to-phase 无关;后继未显式给出时从计划派生(唯一后继自动补跑)。
|
|
3238
|
+
return _resume_closed_phase(project, resolved, args, terminal, as_json=as_json)
|
|
3087
3239
|
resume_run_id = explicit_run_id or _latest_open_run_id(change_dir, args.phase)
|
|
3088
3240
|
return emit_error(
|
|
3089
3241
|
"LEASE_ABSENT",
|
|
@@ -3457,39 +3609,32 @@ def cmd_close(args: argparse.Namespace) -> int:
|
|
|
3457
3609
|
close_transaction["updatedAt"] = he.now_iso()
|
|
3458
3610
|
write_phase_capsule(change_dir, args.phase, run_id, capsule)
|
|
3459
3611
|
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
"leaseReleased": True,
|
|
3487
|
-
"updatedAt": he.now_iso(),
|
|
3488
|
-
})
|
|
3489
|
-
capsule["closedAt"] = he.now_iso()
|
|
3490
|
-
capsule["closeStatus"] = close_status
|
|
3491
|
-
write_phase_capsule(change_dir, args.phase, run_id, capsule)
|
|
3492
|
-
|
|
3612
|
+
# 租约释放必须是关门的最后一个可失败步骤。历史上它排在 handoff/monitor
|
|
3613
|
+
# 之前,一旦中途失败就留下“phase.end 已写 + 租约已放 + 交接没写”的三不管
|
|
3614
|
+
# 状态,重试直接死在 LEASE_ABSENT(2026-08-30 sales-insight-agent 实测)。
|
|
3615
|
+
# 现在顺序为:handoff → monitor → recovery → scratch → release → emit;
|
|
3616
|
+
# 任何中途失败时租约仍持有,重试同一命令按 closeTransaction journal 幂等续跑。
|
|
3617
|
+
# P0-1:plain close 不得静默跳过交接。上下文状态存在且计划后继唯一
|
|
3618
|
+
# (排除 fixback 自环)时自动派生后继并执行交接——断链从根上消失;
|
|
3619
|
+
# 多后继仍要求显式 --to-phase。
|
|
3620
|
+
derived_to_phase: str | None = None
|
|
3621
|
+
if not getattr(args, "to_phase", None):
|
|
3622
|
+
context_view = hctx.context_view(project, str(resolved["changeId"]))
|
|
3623
|
+
if (
|
|
3624
|
+
isinstance(context_view, dict)
|
|
3625
|
+
and context_view.get("ok")
|
|
3626
|
+
and isinstance(context_view.get("current"), dict)
|
|
3627
|
+
):
|
|
3628
|
+
forward = [
|
|
3629
|
+
candidate
|
|
3630
|
+
for candidate in hctx.allowed_next_phases(
|
|
3631
|
+
project, str(resolved["changeId"]), args.phase
|
|
3632
|
+
)
|
|
3633
|
+
if hp.resolve_phase_name(candidate) != args.phase
|
|
3634
|
+
]
|
|
3635
|
+
if len(forward) == 1:
|
|
3636
|
+
derived_to_phase = forward[0]
|
|
3637
|
+
args.to_phase = derived_to_phase
|
|
3493
3638
|
context_handoff = _close_context_handoff(
|
|
3494
3639
|
project,
|
|
3495
3640
|
str(resolved["changeId"]),
|
|
@@ -3517,6 +3662,10 @@ def cmd_close(args: argparse.Namespace) -> int:
|
|
|
3517
3662
|
"changeId": resolved["changeId"],
|
|
3518
3663
|
"contextHandoff": context_handoff,
|
|
3519
3664
|
"platformMonitor": platform_monitor,
|
|
3665
|
+
"recoveryAction": (
|
|
3666
|
+
"租约仍持有,无需重新 claim——原样重跑同一 close 命令即可幂等续跑"
|
|
3667
|
+
"(phase.end 已落会跳过,handoff 会重试)"
|
|
3668
|
+
),
|
|
3520
3669
|
},
|
|
3521
3670
|
)
|
|
3522
3671
|
|
|
@@ -3530,9 +3679,50 @@ def cmd_close(args: argparse.Namespace) -> int:
|
|
|
3530
3679
|
# 直接把归档挡住了。白名单式删除,证据/报告/运行态一律不碰;失败只记不阻断。
|
|
3531
3680
|
try:
|
|
3532
3681
|
scratch_swept = hruntime.sweep_scratch(change_dir)
|
|
3533
|
-
except
|
|
3682
|
+
except Exception as exc: # noqa: BLE001 — 清草稿是收尾便利,任何失败都不得阻断关门
|
|
3534
3683
|
scratch_swept = {"ok": False, "code": "SCRATCH_SWEEP_FAILED", "error": str(exc)}
|
|
3535
3684
|
|
|
3685
|
+
release = hc.release_lease(
|
|
3686
|
+
project,
|
|
3687
|
+
change_id=resolved["changeId"],
|
|
3688
|
+
phase=args.phase,
|
|
3689
|
+
run_id=run_id,
|
|
3690
|
+
)
|
|
3691
|
+
if not release.get("ok"):
|
|
3692
|
+
if capsule is not None:
|
|
3693
|
+
close_transaction.update({
|
|
3694
|
+
"status": "RELEASE_PENDING",
|
|
3695
|
+
"retryable": True,
|
|
3696
|
+
"lastError": release,
|
|
3697
|
+
"updatedAt": he.now_iso(),
|
|
3698
|
+
})
|
|
3699
|
+
write_phase_capsule(change_dir, args.phase, run_id, capsule)
|
|
3700
|
+
return emit_error(
|
|
3701
|
+
str(release.get("code", "LEASE_RELEASE_FAILED")),
|
|
3702
|
+
str(release.get("message", "lease release failed")),
|
|
3703
|
+
as_json=as_json,
|
|
3704
|
+
extra={
|
|
3705
|
+
**{k: v for k, v in release.items() if k not in {"ok", "message", "code"}},
|
|
3706
|
+
"localCloseComplete": True,
|
|
3707
|
+
"retryable": True,
|
|
3708
|
+
"recoveryAction": (
|
|
3709
|
+
"本地关门与上下文交接均已完成,仅租约释放失败——原样重跑同一 close "
|
|
3710
|
+
"命令即幂等续跑(phase.end/handoff 幂等命中,仅重试释放)"
|
|
3711
|
+
),
|
|
3712
|
+
},
|
|
3713
|
+
)
|
|
3714
|
+
|
|
3715
|
+
if capsule is not None:
|
|
3716
|
+
close_transaction.update({
|
|
3717
|
+
"status": "CLOSED",
|
|
3718
|
+
"retryable": False,
|
|
3719
|
+
"leaseReleased": True,
|
|
3720
|
+
"updatedAt": he.now_iso(),
|
|
3721
|
+
})
|
|
3722
|
+
capsule["closedAt"] = he.now_iso()
|
|
3723
|
+
capsule["closeStatus"] = close_status
|
|
3724
|
+
write_phase_capsule(change_dir, args.phase, run_id, capsule)
|
|
3725
|
+
|
|
3536
3726
|
payload = {
|
|
3537
3727
|
"ok": True,
|
|
3538
3728
|
"code": close_code,
|
|
@@ -3553,11 +3743,21 @@ def cmd_close(args: argparse.Namespace) -> int:
|
|
|
3553
3743
|
"gateRecovery": recovery_result,
|
|
3554
3744
|
"scratchSwept": scratch_swept,
|
|
3555
3745
|
}
|
|
3746
|
+
if derived_to_phase is not None:
|
|
3747
|
+
# plain close 自动派生的后继,调用方必须看得到这不是显式选择。
|
|
3748
|
+
payload["derivedToPhase"] = derived_to_phase
|
|
3556
3749
|
if lease_lapsed is not None:
|
|
3557
3750
|
# 与 context transition receipt 的 leaseLapsed 同名同义:记录这个阶段
|
|
3558
3751
|
# 跑过了 TTL 且租约是自动重取的,不隐藏。
|
|
3559
3752
|
payload["leaseLapsed"] = lease_lapsed
|
|
3560
3753
|
emit(payload, as_json=as_json)
|
|
3754
|
+
_emit_close_summary(
|
|
3755
|
+
close_code,
|
|
3756
|
+
args.phase,
|
|
3757
|
+
close_status,
|
|
3758
|
+
getattr(args, "to_phase", None),
|
|
3759
|
+
derived=derived_to_phase is not None,
|
|
3760
|
+
)
|
|
3561
3761
|
return 0
|
|
3562
3762
|
|
|
3563
3763
|
|
|
@@ -3754,7 +3954,11 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
3754
3954
|
p_begin.add_argument("--executor-model", default=None)
|
|
3755
3955
|
p_begin.set_defaults(func=cmd_begin)
|
|
3756
3956
|
|
|
3757
|
-
p_close = sub.add_parser(
|
|
3957
|
+
p_close = sub.add_parser(
|
|
3958
|
+
"close",
|
|
3959
|
+
parents=[shared],
|
|
3960
|
+
help="关闭阶段门禁(关门只调本命令;上下文交接由 --to-phase 内联完成,不要再单独调 harness_context.py close)",
|
|
3961
|
+
)
|
|
3758
3962
|
p_close.add_argument("--phase", required=True)
|
|
3759
3963
|
p_close.add_argument("--change", default=None)
|
|
3760
3964
|
p_close.add_argument(
|
|
@@ -854,13 +854,13 @@ def _node_commands(project: Path) -> dict[str, Any]:
|
|
|
854
854
|
"apps/*/tests/**/*.tsx",
|
|
855
855
|
]
|
|
856
856
|
# harness dogfood: canonical Python + .mjs sources feed npm run check (vitest
|
|
857
|
-
# imports harness-
|
|
857
|
+
# imports harness-execute/scripts; smoke:pack runs sync-harness.mjs).
|
|
858
858
|
if (project / "harness").is_dir():
|
|
859
859
|
inputs.extend(
|
|
860
860
|
[
|
|
861
861
|
"harness/scripts/*.py",
|
|
862
|
-
"harness/harness-
|
|
863
|
-
"harness/harness-
|
|
862
|
+
"harness/harness-execute/scripts/*.mjs",
|
|
863
|
+
"harness/harness-execute/scripts/tests/*.mjs",
|
|
864
864
|
"scripts/*.mjs",
|
|
865
865
|
]
|
|
866
866
|
)
|
|
@@ -575,6 +575,115 @@ def cmd_write_dispositions(args: argparse.Namespace) -> int:
|
|
|
575
575
|
return _emit(write_dispositions(Path(args.change_dir), doc), as_json=True)
|
|
576
576
|
|
|
577
577
|
|
|
578
|
+
def _latest_review_run_id(change_dir: Path) -> str | None:
|
|
579
|
+
"""从 events.ndjson 取最近一轮 review phase.start 的 run_id(best-effort)。"""
|
|
580
|
+
candidates = [change_dir / "events.ndjson"]
|
|
581
|
+
state_events = _state_dir(change_dir) / "events.ndjson"
|
|
582
|
+
if state_events != candidates[0]:
|
|
583
|
+
candidates.append(state_events)
|
|
584
|
+
run_id: str | None = None
|
|
585
|
+
for path in candidates:
|
|
586
|
+
try:
|
|
587
|
+
lines = path.read_text(encoding="utf-8").splitlines()
|
|
588
|
+
except OSError:
|
|
589
|
+
continue
|
|
590
|
+
for line in lines:
|
|
591
|
+
try:
|
|
592
|
+
item = json.loads(line)
|
|
593
|
+
except json.JSONDecodeError:
|
|
594
|
+
continue
|
|
595
|
+
if (
|
|
596
|
+
isinstance(item, dict)
|
|
597
|
+
and item.get("type") == "phase.start"
|
|
598
|
+
and item.get("phase") == "review"
|
|
599
|
+
and isinstance(item.get("run_id"), str)
|
|
600
|
+
and item["run_id"].strip()
|
|
601
|
+
):
|
|
602
|
+
run_id = item["run_id"]
|
|
603
|
+
return run_id
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
def scaffold(change_dir: Path, run_id: str | None) -> dict[str, Any]:
|
|
607
|
+
"""按当前轮次生成 review-findings / fixback-dispositions 的写入骨架。
|
|
608
|
+
|
|
609
|
+
sidecar 的 schema 以前只能从 harness_review.py 源码里挖;骨架直接能喂给
|
|
610
|
+
write-findings / write-dispositions --stdin,消除手拼 JSON 的整类错误。
|
|
611
|
+
已有 findings 时,骨架为每条 finding 生成一条占位处置(disposition=OPEN,
|
|
612
|
+
由调用方逐条改判),并复用 findings 的 runId,保证两份 sidecar 同属一轮。
|
|
613
|
+
"""
|
|
614
|
+
change_dir = Path(change_dir)
|
|
615
|
+
findings_doc = _load_findings(change_dir)
|
|
616
|
+
if findings_doc is not None:
|
|
617
|
+
effective_run_id = str(findings_doc.get("runId") or "").strip()
|
|
618
|
+
if not effective_run_id:
|
|
619
|
+
return {
|
|
620
|
+
"ok": False,
|
|
621
|
+
"code": "FINDINGS_RUN_ID_MISSING",
|
|
622
|
+
"problems": ["review-findings.json 缺少 runId,无法生成同轮处置骨架"],
|
|
623
|
+
}
|
|
624
|
+
dispositions = [
|
|
625
|
+
{"findingId": f["id"], "disposition": "OPEN"}
|
|
626
|
+
for f in findings_doc.get("findings", [])
|
|
627
|
+
if isinstance(f, dict) and isinstance(f.get("id"), str)
|
|
628
|
+
]
|
|
629
|
+
return {
|
|
630
|
+
"ok": True,
|
|
631
|
+
"code": "REVIEW_SCAFFOLD_DISPOSITIONS",
|
|
632
|
+
"runId": effective_run_id,
|
|
633
|
+
"dispositionsInput": {
|
|
634
|
+
"schemaVersion": 1,
|
|
635
|
+
"runId": effective_run_id,
|
|
636
|
+
"dispositions": dispositions,
|
|
637
|
+
},
|
|
638
|
+
"writeCommand": (
|
|
639
|
+
"harness_review.py write-dispositions "
|
|
640
|
+
f"--change-dir {change_dir} --stdin"
|
|
641
|
+
),
|
|
642
|
+
"note": "逐条把 disposition 改判为 FIXED/ACCEPTED_RISK/DEFERRED/NOT_APPLICABLE;"
|
|
643
|
+
"OPEN 表示待修复,gate 关门时所有 finding 都必须有处置记录。",
|
|
644
|
+
}
|
|
645
|
+
effective_run_id = (run_id or "").strip() or _latest_review_run_id(change_dir)
|
|
646
|
+
if not effective_run_id:
|
|
647
|
+
return {
|
|
648
|
+
"ok": False,
|
|
649
|
+
"code": "SCAFFOLD_RUN_ID_REQUIRED",
|
|
650
|
+
"problems": [
|
|
651
|
+
"无法从 events.ndjson 推断本轮 review runId;请显式传 --run-id"
|
|
652
|
+
],
|
|
653
|
+
}
|
|
654
|
+
return {
|
|
655
|
+
"ok": True,
|
|
656
|
+
"code": "REVIEW_SCAFFOLD_FINDINGS",
|
|
657
|
+
"runId": effective_run_id,
|
|
658
|
+
"findingsInput": {
|
|
659
|
+
"schemaVersion": 1,
|
|
660
|
+
"runId": effective_run_id,
|
|
661
|
+
"changeName": change_dir.name,
|
|
662
|
+
"findings": [],
|
|
663
|
+
"_exampleFinding": {
|
|
664
|
+
"dimension": "正确性",
|
|
665
|
+
"severity": "YELLOW",
|
|
666
|
+
"path": "src/example.ts",
|
|
667
|
+
"line": 1,
|
|
668
|
+
"title": "一句话问题标题",
|
|
669
|
+
"fixbackAction": "code",
|
|
670
|
+
},
|
|
671
|
+
},
|
|
672
|
+
"writeCommand": (
|
|
673
|
+
f"harness_review.py write-findings --change-dir {change_dir} --stdin"
|
|
674
|
+
),
|
|
675
|
+
"note": "无发现时保持 findings 为空数组即合法;write-findings 会为每条 "
|
|
676
|
+
"finding 分配稳定 id。落地后重跑 scaffold 生成对应的处置骨架。",
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
def cmd_scaffold(args: argparse.Namespace) -> int:
|
|
681
|
+
return _emit(
|
|
682
|
+
scaffold(Path(args.change_dir), getattr(args, "run_id", None)),
|
|
683
|
+
as_json=True,
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
|
|
578
687
|
def cmd_status(args: argparse.Namespace) -> int:
|
|
579
688
|
return _emit(status(Path(args.change_dir)), as_json=True)
|
|
580
689
|
|
|
@@ -611,6 +720,17 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
611
720
|
)
|
|
612
721
|
p_dispositions.set_defaults(func=cmd_write_dispositions)
|
|
613
722
|
|
|
723
|
+
p_scaffold = sub.add_parser(
|
|
724
|
+
"scaffold",
|
|
725
|
+
help="按当前轮次生成 review-findings / fixback-dispositions 的写入骨架",
|
|
726
|
+
)
|
|
727
|
+
p_scaffold.add_argument("--change-dir", required=True)
|
|
728
|
+
p_scaffold.add_argument(
|
|
729
|
+
"--run-id",
|
|
730
|
+
help="本轮 review runId;缺省从 events.ndjson 最新的 review phase.start 推断",
|
|
731
|
+
)
|
|
732
|
+
p_scaffold.set_defaults(func=cmd_scaffold)
|
|
733
|
+
|
|
614
734
|
p_status = sub.add_parser("status")
|
|
615
735
|
p_status.add_argument("--change-dir", required=True)
|
|
616
736
|
p_status.set_defaults(func=cmd_status)
|
|
@@ -324,6 +324,7 @@ def _sensitive_candidates(
|
|
|
324
324
|
for pattern in (_SENSITIVE_ASSIGNMENT, _AUTHORIZATION_ASSIGNMENT)
|
|
325
325
|
for match in pattern.finditer(raw)
|
|
326
326
|
if not _is_sensitive_placeholder(match.group("value"))
|
|
327
|
+
and not _is_harness_internal_key(raw, match)
|
|
327
328
|
),
|
|
328
329
|
None,
|
|
329
330
|
)
|
|
@@ -337,6 +338,18 @@ def _sensitive_candidates(
|
|
|
337
338
|
return candidates
|
|
338
339
|
|
|
339
340
|
|
|
341
|
+
def _is_harness_internal_key(raw: bytes, match: re.Match[bytes]) -> bool:
|
|
342
|
+
"""harness 自己生成的系统字段不是用户秘密。
|
|
343
|
+
|
|
344
|
+
plan finalize 发布日志(meta/publication-journals/*.json)里的
|
|
345
|
+
``recovery_token`` 是内部续跑凭证,会被通用 ``token`` 规则误伤
|
|
346
|
+
(2026-08-30 sales-insight-agent archive 实测:两个发布日志串行阻断)。
|
|
347
|
+
正则从关键字(如 ``token``)处起匹配,豁免看关键字前面的字段名前缀。
|
|
348
|
+
"""
|
|
349
|
+
prefix = raw[max(0, match.start() - 16):match.start()]
|
|
350
|
+
return bool(re.search(rb'(?i)recovery_["\']?$', prefix))
|
|
351
|
+
|
|
352
|
+
|
|
340
353
|
def _is_sensitive_placeholder(value: bytes) -> bool:
|
|
341
354
|
text = value.decode("utf-8", errors="ignore").strip().strip("`'").strip()
|
|
342
355
|
return bool(
|