@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
|
@@ -27,6 +27,12 @@ import sys
|
|
|
27
27
|
from pathlib import Path
|
|
28
28
|
from typing import Any
|
|
29
29
|
|
|
30
|
+
SCRIPTS_DIR = Path(__file__).resolve().parent
|
|
31
|
+
if str(SCRIPTS_DIR) not in sys.path:
|
|
32
|
+
sys.path.insert(0, str(SCRIPTS_DIR))
|
|
33
|
+
|
|
34
|
+
import harness_paths # noqa: E402
|
|
35
|
+
|
|
30
36
|
|
|
31
37
|
if hasattr(sys.stdout, "reconfigure"):
|
|
32
38
|
sys.stdout.reconfigure(encoding="utf-8")
|
|
@@ -358,14 +364,53 @@ def empty_profile_skeleton(excluded: tuple[str, ...] | list[str]) -> dict[str, A
|
|
|
358
364
|
|
|
359
365
|
|
|
360
366
|
def load_profile(project: Path) -> dict[str, Any] | None:
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
+
"""C7: 分层读取 — 先读 common_root 的 build-profile.json,再叠加 execution root 的 override。
|
|
368
|
+
|
|
369
|
+
common_root 是 worktree 共享的主项目根(git common dir 的父目录);
|
|
370
|
+
execution root 是当前工作目录(可能是 linked worktree)。
|
|
371
|
+
override 合并策略:execution 的 buildCommands 覆盖 common 的同名 key;
|
|
372
|
+
common 独有的 key 保留。
|
|
373
|
+
"""
|
|
374
|
+
project = Path(project).resolve()
|
|
375
|
+
common = harness_paths.common_root(project)
|
|
376
|
+
common_path = common / PROFILE_REL
|
|
377
|
+
exec_path = project / PROFILE_REL
|
|
378
|
+
|
|
379
|
+
common_data: dict[str, Any] | None = None
|
|
380
|
+
if common_path.is_file():
|
|
381
|
+
try:
|
|
382
|
+
data = read_json(common_path)
|
|
383
|
+
if isinstance(data, dict):
|
|
384
|
+
common_data = data
|
|
385
|
+
except (OSError, json.JSONDecodeError):
|
|
386
|
+
pass
|
|
387
|
+
|
|
388
|
+
exec_data: dict[str, Any] | None = None
|
|
389
|
+
if exec_path.is_file():
|
|
390
|
+
try:
|
|
391
|
+
data = read_json(exec_path)
|
|
392
|
+
if isinstance(data, dict):
|
|
393
|
+
exec_data = data
|
|
394
|
+
except (OSError, json.JSONDecodeError):
|
|
395
|
+
pass
|
|
396
|
+
|
|
397
|
+
if common_data is None and exec_data is None:
|
|
367
398
|
return None
|
|
368
|
-
|
|
399
|
+
if common_data is None:
|
|
400
|
+
return exec_data
|
|
401
|
+
if exec_data is None:
|
|
402
|
+
return common_data
|
|
403
|
+
|
|
404
|
+
# Merge: start from common, overlay execution's buildCommands.
|
|
405
|
+
merged = dict(common_data)
|
|
406
|
+
common_cmds = common_data.get("buildCommands") or {}
|
|
407
|
+
exec_cmds = exec_data.get("buildCommands") or {}
|
|
408
|
+
if common_cmds or exec_cmds:
|
|
409
|
+
merged_cmds = dict(common_cmds) if isinstance(common_cmds, dict) else {}
|
|
410
|
+
if isinstance(exec_cmds, dict):
|
|
411
|
+
merged_cmds.update(exec_cmds)
|
|
412
|
+
merged["buildCommands"] = merged_cmds
|
|
413
|
+
return merged
|
|
369
414
|
|
|
370
415
|
|
|
371
416
|
def _merge_user_overrides(
|
|
@@ -616,6 +661,8 @@ def resolve_command(
|
|
|
616
661
|
*,
|
|
617
662
|
test_classes: list[str] | None = None,
|
|
618
663
|
modules: list[str] | None = None,
|
|
664
|
+
common_root: Path | None = None,
|
|
665
|
+
execution_root: Path | None = None,
|
|
619
666
|
) -> dict[str, Any]:
|
|
620
667
|
cmd = (profile.get("commands") or {}).get(key)
|
|
621
668
|
if not isinstance(cmd, dict):
|
|
@@ -625,6 +672,10 @@ def resolve_command(
|
|
|
625
672
|
replacements["{testClasses}"] = ",".join(test_classes)
|
|
626
673
|
if modules is not None:
|
|
627
674
|
replacements["{modules}"] = ",".join(modules)
|
|
675
|
+
if common_root is not None:
|
|
676
|
+
replacements["{commonRoot}"] = str(common_root)
|
|
677
|
+
if execution_root is not None:
|
|
678
|
+
replacements["{executionRoot}"] = str(execution_root)
|
|
628
679
|
|
|
629
680
|
command = cmd.get("command", "")
|
|
630
681
|
for placeholder, val in replacements.items():
|
|
@@ -14,6 +14,7 @@ Python 3.10+, stdlib only.
|
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
16
|
import argparse
|
|
17
|
+
import datetime as dt
|
|
17
18
|
import hashlib
|
|
18
19
|
import json
|
|
19
20
|
import os
|
|
@@ -270,6 +271,112 @@ def _emit(payload: Any, *, as_json: bool) -> int:
|
|
|
270
271
|
return 0 if payload.get("ok") else 1
|
|
271
272
|
|
|
272
273
|
|
|
274
|
+
def dispatch_review(
|
|
275
|
+
*,
|
|
276
|
+
change_dir: Path,
|
|
277
|
+
run_id: str,
|
|
278
|
+
budget_seconds: int = 300,
|
|
279
|
+
) -> dict[str, Any]:
|
|
280
|
+
"""C11: dispatch a bounded review task.
|
|
281
|
+
|
|
282
|
+
Returns reviewTaskId / deadline / heartbeatAt. The caller is expected to
|
|
283
|
+
poll the review subagent and collect partial findings on timeout.
|
|
284
|
+
"""
|
|
285
|
+
now = dt.datetime.now(dt.timezone.utc).astimezone()
|
|
286
|
+
task_id = f"review-{uuid.uuid4().hex}"
|
|
287
|
+
deadline = now + dt.timedelta(seconds=budget_seconds)
|
|
288
|
+
# heartbeat at midpoint of the budget
|
|
289
|
+
heartbeat = now + dt.timedelta(seconds=budget_seconds // 2)
|
|
290
|
+
return {
|
|
291
|
+
"ok": True,
|
|
292
|
+
"code": "DISPATCHED",
|
|
293
|
+
"reviewTaskId": task_id,
|
|
294
|
+
"runId": run_id,
|
|
295
|
+
"deadline": deadline.isoformat(timespec="milliseconds"),
|
|
296
|
+
"heartbeatAt": heartbeat.isoformat(timespec="milliseconds"),
|
|
297
|
+
"budgetSeconds": budget_seconds,
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def collect_partial_findings(
|
|
302
|
+
*,
|
|
303
|
+
change_dir: Path,
|
|
304
|
+
run_id: str,
|
|
305
|
+
completed_dimensions: list[str],
|
|
306
|
+
pending_dimensions: list[str],
|
|
307
|
+
) -> dict[str, Any]:
|
|
308
|
+
"""C11: collect partial findings after timeout — completed dimensions only.
|
|
309
|
+
|
|
310
|
+
Applies the degradation matrix to decide the fallback path.
|
|
311
|
+
"""
|
|
312
|
+
matrix = degradation_matrix(
|
|
313
|
+
subagent_timed_out=bool(pending_dimensions),
|
|
314
|
+
main_session_available=True,
|
|
315
|
+
)
|
|
316
|
+
return {
|
|
317
|
+
"ok": True,
|
|
318
|
+
"code": "PARTIAL_FINDINGS",
|
|
319
|
+
"runId": run_id,
|
|
320
|
+
"completedDimensions": list(completed_dimensions),
|
|
321
|
+
"pendingDimensions": list(pending_dimensions),
|
|
322
|
+
"degradationMatrix": matrix,
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def degradation_matrix(
|
|
327
|
+
*,
|
|
328
|
+
subagent_timed_out: bool,
|
|
329
|
+
main_session_available: bool,
|
|
330
|
+
) -> dict[str, Any]:
|
|
331
|
+
"""C11: degradation matrix — subagent timeout → main session; main fail → ADVISORY."""
|
|
332
|
+
if not subagent_timed_out:
|
|
333
|
+
return {"fallback": "none", "status": "OK"}
|
|
334
|
+
if main_session_available:
|
|
335
|
+
return {"fallback": "main-session", "status": "DEGRADED"}
|
|
336
|
+
return {"fallback": "advisory", "status": "ADVISORY"}
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def validate_codegraph_identity(
|
|
340
|
+
*,
|
|
341
|
+
response: dict[str, Any],
|
|
342
|
+
expected_repository_id: str,
|
|
343
|
+
expected_head: str,
|
|
344
|
+
) -> dict[str, Any]:
|
|
345
|
+
"""C12: validate CodeGraph identity — repositoryId/indexedHead must match.
|
|
346
|
+
|
|
347
|
+
On mismatch, signal CODEGRAPH_IDENTITY_MISMATCH with fallback to Grep/Glob + Read.
|
|
348
|
+
"""
|
|
349
|
+
repo_id = response.get("repositoryId")
|
|
350
|
+
indexed_head = response.get("indexedHead")
|
|
351
|
+
indexed_at = response.get("indexedAt")
|
|
352
|
+
if (
|
|
353
|
+
repo_id == expected_repository_id
|
|
354
|
+
and indexed_head == expected_head
|
|
355
|
+
and indexed_at
|
|
356
|
+
):
|
|
357
|
+
return {
|
|
358
|
+
"ok": True,
|
|
359
|
+
"code": "IDENTITY_OK",
|
|
360
|
+
"repositoryId": repo_id,
|
|
361
|
+
"indexedHead": indexed_head,
|
|
362
|
+
"indexedAt": indexed_at,
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
"ok": False,
|
|
366
|
+
"code": "CODEGRAPH_IDENTITY_MISMATCH",
|
|
367
|
+
"expected": {
|
|
368
|
+
"repositoryId": expected_repository_id,
|
|
369
|
+
"indexedHead": expected_head,
|
|
370
|
+
},
|
|
371
|
+
"actual": {
|
|
372
|
+
"repositoryId": repo_id,
|
|
373
|
+
"indexedHead": indexed_head,
|
|
374
|
+
"indexedAt": indexed_at,
|
|
375
|
+
},
|
|
376
|
+
"fallback": "grep-glob-read",
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
|
|
273
380
|
def cmd_validate_findings(args: argparse.Namespace) -> int:
|
|
274
381
|
doc = _read_json(Path(args.input))
|
|
275
382
|
problems = validate_findings(doc)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Controlled cleanup helper for test fixtures (retro §5.23).
|
|
3
|
+
|
|
4
|
+
Provides a host-policy-friendly entry point for removing gitignored test
|
|
5
|
+
fixtures (e.g. .pytest_data) within an execution root. Performs realpath
|
|
6
|
+
containment, rejects symlink/reparse escapes, lists exact counts before
|
|
7
|
+
deletion, and outputs a structured receipt.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import shutil
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
20
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
21
|
+
if hasattr(sys.stderr, "reconfigure"):
|
|
22
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _resolve_within(execution_root: Path, rel: str) -> Path | None:
|
|
26
|
+
"""Resolve rel under execution_root, rejecting escapes and symlinks."""
|
|
27
|
+
if not rel or rel.startswith("/"):
|
|
28
|
+
return None
|
|
29
|
+
# Reject absolute paths (Windows drive letter or POSIX).
|
|
30
|
+
if len(rel) >= 2 and rel[1] == ":":
|
|
31
|
+
return None
|
|
32
|
+
parts = rel.replace("\\", "/").split("/")
|
|
33
|
+
if ".." in parts:
|
|
34
|
+
return None
|
|
35
|
+
candidate = (execution_root / rel).resolve(strict=False)
|
|
36
|
+
# Containment check: candidate must be under execution_root.
|
|
37
|
+
try:
|
|
38
|
+
candidate.relative_to(execution_root.resolve(strict=False))
|
|
39
|
+
except ValueError:
|
|
40
|
+
return None
|
|
41
|
+
# Reject symlink/reparse escape: if the path is a symlink, check its target.
|
|
42
|
+
if candidate.is_symlink():
|
|
43
|
+
target = Path(os.readlink(candidate)).resolve(strict=False)
|
|
44
|
+
try:
|
|
45
|
+
target.relative_to(execution_root.resolve(strict=False))
|
|
46
|
+
except ValueError:
|
|
47
|
+
return None
|
|
48
|
+
# Even if target is inside, a symlinked cleanup root is suspicious;
|
|
49
|
+
# reject to avoid following links into unexpected locations.
|
|
50
|
+
return None
|
|
51
|
+
return candidate
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _count_files(root: Path) -> tuple[int, int]:
|
|
55
|
+
"""Count files and total bytes under root."""
|
|
56
|
+
count = 0
|
|
57
|
+
total = 0
|
|
58
|
+
for dirpath, _dirs, files in os.walk(root):
|
|
59
|
+
for name in files:
|
|
60
|
+
fp = Path(dirpath) / name
|
|
61
|
+
try:
|
|
62
|
+
total += fp.stat().st_size
|
|
63
|
+
count += 1
|
|
64
|
+
except OSError:
|
|
65
|
+
continue
|
|
66
|
+
return count, total
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def cleanup(execution_root: Path, cleanup_roots: list[str]) -> dict[str, Any]:
|
|
70
|
+
"""Remove allowlisted cleanup roots within execution_root.
|
|
71
|
+
|
|
72
|
+
Returns a structured receipt. Any path escape, symlink escape, or
|
|
73
|
+
unallowed root results in ok=false with zero files removed.
|
|
74
|
+
"""
|
|
75
|
+
execution_root = Path(execution_root).resolve(strict=False)
|
|
76
|
+
if not execution_root.is_dir():
|
|
77
|
+
return {
|
|
78
|
+
"ok": False,
|
|
79
|
+
"code": "EXECUTION_ROOT_MISSING",
|
|
80
|
+
"executionRoot": str(execution_root),
|
|
81
|
+
"removedFiles": 0,
|
|
82
|
+
"removedBytes": 0,
|
|
83
|
+
"rejectedEscapes": [],
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
rejected: list[dict[str, str]] = []
|
|
87
|
+
removed_files = 0
|
|
88
|
+
removed_bytes = 0
|
|
89
|
+
cleaned: list[str] = []
|
|
90
|
+
|
|
91
|
+
for rel in cleanup_roots:
|
|
92
|
+
target = _resolve_within(execution_root, rel)
|
|
93
|
+
if target is None:
|
|
94
|
+
rejected.append({"path": rel, "reason": "PATH_ESCAPE_REJECTED"})
|
|
95
|
+
continue
|
|
96
|
+
if not target.exists():
|
|
97
|
+
# Already absent — idempotent reentry.
|
|
98
|
+
continue
|
|
99
|
+
# Re-check symlink after resolution (the parent might be a symlink).
|
|
100
|
+
if target.is_symlink():
|
|
101
|
+
rejected.append({"path": rel, "reason": "SYMLINK_ESCAPE_REJECTED"})
|
|
102
|
+
continue
|
|
103
|
+
# Count before deletion for the receipt.
|
|
104
|
+
try:
|
|
105
|
+
count, total = _count_files(target)
|
|
106
|
+
except OSError:
|
|
107
|
+
count, total = 0, 0
|
|
108
|
+
# Delete.
|
|
109
|
+
try:
|
|
110
|
+
shutil.rmtree(target)
|
|
111
|
+
except OSError as exc:
|
|
112
|
+
rejected.append({"path": rel, "reason": f"DELETE_FAILED: {exc}"})
|
|
113
|
+
continue
|
|
114
|
+
removed_files += count
|
|
115
|
+
removed_bytes += total
|
|
116
|
+
cleaned.append(rel)
|
|
117
|
+
|
|
118
|
+
if rejected:
|
|
119
|
+
return {
|
|
120
|
+
"ok": False,
|
|
121
|
+
"code": rejected[0]["reason"],
|
|
122
|
+
"executionRoot": str(execution_root),
|
|
123
|
+
"removedFiles": removed_files,
|
|
124
|
+
"removedBytes": removed_bytes,
|
|
125
|
+
"rejectedEscapes": rejected,
|
|
126
|
+
"cleaned": cleaned,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if removed_files == 0 and not cleaned:
|
|
130
|
+
return {
|
|
131
|
+
"ok": True,
|
|
132
|
+
"code": "ALREADY_ABSENT",
|
|
133
|
+
"executionRoot": str(execution_root),
|
|
134
|
+
"removedFiles": 0,
|
|
135
|
+
"removedBytes": 0,
|
|
136
|
+
"rejectedEscapes": [],
|
|
137
|
+
"cleaned": [],
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
"ok": True,
|
|
142
|
+
"code": "CLEANUP_COMPLETE",
|
|
143
|
+
"executionRoot": str(execution_root),
|
|
144
|
+
"removedFiles": removed_files,
|
|
145
|
+
"removedBytes": removed_bytes,
|
|
146
|
+
"rejectedEscapes": [],
|
|
147
|
+
"cleaned": cleaned,
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def main(argv: list[str] | None = None) -> int:
|
|
152
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
153
|
+
sub = parser.add_subparsers(dest="action", required=True)
|
|
154
|
+
clean_parser = sub.add_parser("cleanup")
|
|
155
|
+
clean_parser.add_argument("--execution-root", required=True)
|
|
156
|
+
clean_parser.add_argument("--cleanup-roots", required=True, help="JSON array of relative paths")
|
|
157
|
+
clean_parser.add_argument("--json", action="store_true")
|
|
158
|
+
args = parser.parse_args(argv)
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
roots = json.loads(args.cleanup_roots)
|
|
162
|
+
if not isinstance(roots, list):
|
|
163
|
+
raise ValueError("cleanup-roots must be a JSON array")
|
|
164
|
+
except (json.JSONDecodeError, ValueError) as exc:
|
|
165
|
+
result = {"ok": False, "code": "INVALID_CLEANUP_ROOTS", "error": str(exc)}
|
|
166
|
+
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
167
|
+
return 1
|
|
168
|
+
|
|
169
|
+
result = cleanup(Path(args.execution_root), roots)
|
|
170
|
+
print(json.dumps(result, ensure_ascii=False, indent=2 if args.json else None))
|
|
171
|
+
return 0 if result["ok"] else 1
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
if __name__ == "__main__":
|
|
175
|
+
raise SystemExit(main())
|
|
@@ -53,9 +53,22 @@ _Avoid_: 仅凭 diffHash 复用, 无证据跳过
|
|
|
53
53
|
_Avoid_: 每轮测试后必杀服务
|
|
54
54
|
|
|
55
55
|
**交互白名单**:
|
|
56
|
-
每个 skill 显式声明的允许
|
|
56
|
+
每个 skill 显式声明的允许 `blocking user confirmation` 场景清单。白名单外一律取默认值并记 decision 事件。
|
|
57
57
|
_Avoid_: 逐决策点询问
|
|
58
58
|
|
|
59
|
+
**阻断式用户确认(blocking user confirmation)**:
|
|
60
|
+
宿主无关的审批原语。canonical skill 使用此术语表达"展示完整审批包并等待明确答复"的语义,不绑定具体宿主工具。adapter 按下表映射到宿主具体工具:
|
|
61
|
+
|
|
62
|
+
| Adapter | 工具 |
|
|
63
|
+
|---------|------|
|
|
64
|
+
| claude-code | AskUserQuestion |
|
|
65
|
+
| codebuddy | AskUserQuestion |
|
|
66
|
+
| codex | request_user_input 或普通对话 |
|
|
67
|
+
| cursor | 普通对话 |
|
|
68
|
+
|
|
69
|
+
finalizer 只校验 approval receipt/decision 的顺序和内容,不校验交互工具品牌。
|
|
70
|
+
_Avoid_: 硬编码宿主工具名, 跨宿主不可移植
|
|
71
|
+
|
|
59
72
|
**部署合成**:
|
|
60
73
|
`harness_deploy.py build` 把通用核心 + shared 片段 + overlay 合成为自包含 SKILL.md 后部署。Vault 源头 DRY,运行时单文件。
|
|
61
74
|
_Avoid_: 运行时跨文件拼规则, fork 维护
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
| harness-knowledge-query | `[Bash(powershell.exe:*), Read, Write, Edit, Glob, Grep]` | 同上 |
|
|
60
60
|
| harness-knowledge-ingest | `[Bash(powershell.exe:*), Read, Write, Edit, Glob, Grep]` | 同上 |
|
|
61
61
|
|
|
62
|
-
> **
|
|
62
|
+
> **blocking user confirmation 不预批准**:各 skill 需要向用户确认时通过普通权限提示调用 `blocking user confirmation`(adapter 映射到 `AskUserQuestion`/`request_user_input`/普通对话),不在 `allowed-tools` 中预批准(遵循 skill-optimizer 规则)。`harness-codebase-map` 额外预批准 `Agent` 用于派发并行 mapper。
|
|
63
63
|
|
|
64
64
|
> **codegraph 命令**:原 `Bash(codegraph *)` 改为 MCP 工具调用(`mcp__codegraph__codegraph_explore` 等),不再通过 Bash。
|
|
65
65
|
>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: harness-apidoc
|
|
3
3
|
description: 从 Java 后端代码生成结构化前端 API 文档(Controller/VO/ErrorCode)。使用场景:接口文档、前端接口文档、API 文档生成
|
|
4
4
|
---
|
|
5
|
-
<!-- generated by harness_deploy.py; core=
|
|
5
|
+
<!-- generated by harness_deploy.py; core=6a9274f7a054dc17; overlay=java; agent=codex; do not edit -->
|
|
6
6
|
# harness-apidoc — 前端接口文档(Java overlay)
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
@@ -27,6 +27,7 @@ description: 从 Java 后端代码生成结构化前端 API 文档(Controller/
|
|
|
27
27
|
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 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
|
|
28
28
|
|
|
29
29
|
状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
|
|
30
|
+
> 片段:read-protocol
|
|
30
31
|
|
|
31
32
|
## Workflow
|
|
32
33
|
|
|
@@ -52,6 +53,7 @@ description: 从 Java 后端代码生成结构化前端 API 文档(Controller/
|
|
|
52
53
|
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
53
54
|
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
54
55
|
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
56
|
+
> 片段:p0-trust
|
|
55
57
|
|
|
56
58
|
## 渐进披露
|
|
57
59
|
|
|
@@ -60,7 +62,7 @@ description: 从 Java 后端代码生成结构化前端 API 文档(Controller/
|
|
|
60
62
|
|
|
61
63
|
## 交互白名单
|
|
62
64
|
|
|
63
|
-
**无**
|
|
65
|
+
**无** blocking user confirmation;缺输入记 `issue`。
|
|
64
66
|
|
|
65
67
|
## 执行日志
|
|
66
68
|
|
|
@@ -75,3 +77,4 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
75
77
|
> **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 边界保持最新。
|
|
76
78
|
|
|
77
79
|
每次阶段结束必须写 `--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` 环境变量统一注入。
|
|
80
|
+
> 片段:logging · phase=`apidoc`
|
|
@@ -3,7 +3,7 @@ name: harness-archive
|
|
|
3
3
|
description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档)到
|
|
4
4
|
.harness/archive/,含归档元数据和可视化最终总结。使用场景:归档、完成归档、收尾、打包产出物
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=6a9274f7a054dc17; overlay=java; agent=codex; do not edit -->
|
|
7
7
|
# harness-archive — 变更归档
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -52,6 +52,7 @@ description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档
|
|
|
52
52
|
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 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
|
|
53
53
|
|
|
54
54
|
状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
|
|
55
|
+
> 片段:read-protocol
|
|
55
56
|
|
|
56
57
|
## Workflow
|
|
57
58
|
|
|
@@ -79,7 +80,7 @@ description: 归档所有变更产出(计划/测试报告/审查/SQL/API文档
|
|
|
79
80
|
|
|
80
81
|
### Phase 2:确认归档 ⚠️ 强制阻断
|
|
81
82
|
|
|
82
|
-
|
|
83
|
+
blocking user confirmation 让用户确认归档操作。**用户拒绝 → 终止流程,不执行任何操作。**
|
|
83
84
|
|
|
84
85
|
- **Read `reference.md`** — 确认对话框的内容格式
|
|
85
86
|
|
|
@@ -104,6 +105,7 @@ AskUserQuestion 让用户确认归档操作。**用户拒绝 → 终止流程,
|
|
|
104
105
|
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
105
106
|
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
106
107
|
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
108
|
+
> 片段:p0-trust
|
|
107
109
|
|
|
108
110
|
## 关键规则(硬门禁速查)
|
|
109
111
|
|
|
@@ -115,7 +117,7 @@ AskUserQuestion 让用户确认归档操作。**用户拒绝 → 终止流程,
|
|
|
115
117
|
|
|
116
118
|
### 二、归档前确认是强制阻断检查点
|
|
117
119
|
|
|
118
|
-
|
|
120
|
+
blocking user confirmation 确认;用户拒绝 → 终止,不执行任何操作。
|
|
119
121
|
|
|
120
122
|
### 三、文件移动只用内置工具或 PowerShell
|
|
121
123
|
|
|
@@ -184,7 +186,7 @@ git 命令通过 `powershell.exe -Command "..."` 执行;archive-meta.md 和 fi
|
|
|
184
186
|
|
|
185
187
|
## 交互白名单
|
|
186
188
|
|
|
187
|
-
**仅允许**归档确认(Phase 2
|
|
189
|
+
**仅允许**归档确认(Phase 2 blocking user confirmation);拒绝 → 终止,不执行任何移动。
|
|
188
190
|
|
|
189
191
|
## 执行日志
|
|
190
192
|
|
|
@@ -199,3 +201,4 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
199
201
|
> **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 边界保持最新。
|
|
200
202
|
|
|
201
203
|
每次阶段结束必须写 `--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` 环境变量统一注入。
|
|
204
|
+
> 片段:logging · phase=`archive`
|
|
@@ -8,7 +8,7 @@ description: harness-archive 的归档流程、manifest、summary-data、final-s
|
|
|
8
8
|
|
|
9
9
|
- **Phase 0 读取上下文**:读 SKILL.md / 本文件 / 共用协议(`../protocols/archive-report-protocol.md`、`../protocols/report-pipeline-protocol.md`、`../protocols/state-layout-protocol.md`、`../protocols/powershell-protocol.md`、`../protocols/sensitive-info-protocol.md`、`../protocols/evidence-based-reporting-protocol.md`)/ 解析 `$ARGUMENTS`。
|
|
10
10
|
- **Phase 1 确认归档对象**:Glob `.harness/changes/*/plans/*-plan.md`(排除 archive),展示概要;多变更让用户选择或终止。
|
|
11
|
-
- **Phase 2 确认归档(强制阻断)**:
|
|
11
|
+
- **Phase 2 确认归档(强制阻断)**:blocking user confirmation 确认,拒绝即终止。
|
|
12
12
|
- **Phase 3 执行归档**:
|
|
13
13
|
1. 运行 `python <skills-root>/scripts/harness_archive.py status --change-dir ... --json` 做前置检查。
|
|
14
14
|
2. `meta/archive-meta.md` 由 finalize 生成(与 summary `finalStatus` 同源);禁止手写。维护者结论写入 events 即可。finalize 在 before-manifest 前执行 cleanup(删除 lock/pid/launcher/credential,截断超大日志)。
|
|
@@ -3,7 +3,7 @@ name: harness-codebase-map
|
|
|
3
3
|
description: 分析现有代码库并生成 .harness/codebase/map/
|
|
4
4
|
下的结构化代码库地图。用于陌生项目理解、重大改造前梳理、harness-sync 提示 map 过期后的人工刷新。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=6a9274f7a054dc17; overlay=java; agent=codex; do not edit -->
|
|
7
7
|
# harness-codebase-map — 代码库地图
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
@@ -56,6 +56,7 @@ description: 分析现有代码库并生成 .harness/codebase/map/
|
|
|
56
56
|
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
57
57
|
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
58
58
|
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
59
|
+
> 片段:p0-trust · map 额外:文件存在/行数/hash 为证据
|
|
59
60
|
|
|
60
61
|
## 关键规则
|
|
61
62
|
|
|
@@ -81,7 +82,7 @@ description: 分析现有代码库并生成 .harness/codebase/map/
|
|
|
81
82
|
|
|
82
83
|
## 交互白名单
|
|
83
84
|
|
|
84
|
-
**无**
|
|
85
|
+
**无** blocking user confirmation;参数/默认值 + `decision` 事件
|
|
85
86
|
|
|
86
87
|
## 执行日志
|
|
87
88
|
|
|
@@ -96,3 +97,4 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
96
97
|
> **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 边界保持最新。
|
|
97
98
|
|
|
98
99
|
每次阶段结束必须写 `--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` 环境变量统一注入。
|
|
100
|
+
> 片段:logging · phase=`codebase-map`;默认写 reports,有未归档变更时另写 change events
|
|
@@ -3,7 +3,7 @@ name: harness-knowledge-ingest
|
|
|
3
3
|
description: 从 .harness/archive 归档整理、同步和维护项目知识索引。适用场景:ingest knowledge、sync
|
|
4
4
|
knowledge、rebuild knowledge index、promote knowledge、确认知识条目、检查知识库是否过期。
|
|
5
5
|
---
|
|
6
|
-
<!-- generated by harness_deploy.py; core=
|
|
6
|
+
<!-- generated by harness_deploy.py; core=6a9274f7a054dc17; overlay=java; agent=codex; do not edit -->
|
|
7
7
|
# harness-knowledge-ingest
|
|
8
8
|
|
|
9
9
|
从 `.harness/archive/**/reports/final/summary-data.json` 抽取项目知识,生成并维护本地 `.harness/knowledge/` 索引。
|
|
@@ -211,6 +211,7 @@ powershell.exe -Command "python '<skill-dir>\scripts\harness_knowledge.py' sync
|
|
|
211
211
|
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
212
212
|
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
213
213
|
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
214
|
+
> 片段:p0-trust · ingest/sync 须绑定 `upToDate`/产物路径证据
|
|
214
215
|
|
|
215
216
|
## Output Format
|
|
216
217
|
|
|
@@ -230,7 +231,7 @@ powershell.exe -Command "python '<skill-dir>\scripts\harness_knowledge.py' sync
|
|
|
230
231
|
|
|
231
232
|
## 交互白名单
|
|
232
233
|
|
|
233
|
-
**仅当** `.harness/config/harness.json` 中 `knowledge.manualReview=true` 时,promote/demote 高价值条目需
|
|
234
|
+
**仅当** `.harness/config/harness.json` 中 `knowledge.manualReview=true` 时,promote/demote 高价值条目需 blocking user confirmation;否则按 skill 默认策略 + `decision` 事件。
|
|
234
235
|
|
|
235
236
|
## 执行日志
|
|
236
237
|
|
|
@@ -245,3 +246,4 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
245
246
|
> **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 边界保持最新。
|
|
246
247
|
|
|
247
248
|
每次阶段结束必须写 `--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` 环境变量统一注入。
|
|
249
|
+
> 片段:logging · phase=`knowledge-ingest` · 默认控制台报告;变更上下文写 phase/decision/issue/artifact
|
|
@@ -4552,6 +4552,11 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
4552
4552
|
query.add_argument("--status", action="append", dest="statuses", default=[], help="Only return entries with this lifecycle status")
|
|
4553
4553
|
query.add_argument("--type", action="append", dest="types", default=[], help="Only return entries of this knowledge type")
|
|
4554
4554
|
query.add_argument("--change", default=None, help="Write a change-scoped knowledge-context pointer")
|
|
4555
|
+
query.add_argument(
|
|
4556
|
+
"--verbose",
|
|
4557
|
+
action="store_true",
|
|
4558
|
+
help="Emit full payload including matches array (default: compact output for host decisioning)",
|
|
4559
|
+
)
|
|
4555
4560
|
|
|
4556
4561
|
promote = sub.add_parser("promote", help="Promote a candidate knowledge entry to active")
|
|
4557
4562
|
promote.add_argument("--project", default=".", help="Project root containing .harness/knowledge")
|
|
@@ -4652,7 +4657,17 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
4652
4657
|
Path(args.project), args.query, args.limit, args.files, args.statuses,
|
|
4653
4658
|
args.types, args.change,
|
|
4654
4659
|
)
|
|
4655
|
-
|
|
4660
|
+
if getattr(args, "verbose", False):
|
|
4661
|
+
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
4662
|
+
else:
|
|
4663
|
+
# C5: compact output — omit matches array; host reads context pack for details.
|
|
4664
|
+
compact = {
|
|
4665
|
+
"query": result["query"],
|
|
4666
|
+
"matchCount": result["matchCount"],
|
|
4667
|
+
"contextPack": result["contextPack"],
|
|
4668
|
+
"planInput": result["planInput"],
|
|
4669
|
+
}
|
|
4670
|
+
print(json.dumps(compact, ensure_ascii=False, indent=2))
|
|
4656
4671
|
return 0
|
|
4657
4672
|
if args.command == "promote":
|
|
4658
4673
|
try:
|