@hunter-harness/workflow-harness 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/harness/bundles/general/claude-code/.harness-build.json +1 -1
- package/harness/bundles/general/claude-code/contracts/workflow-policy.json +169 -0
- package/harness/bundles/general/claude-code/harness-archive/SKILL.md +7 -2
- package/harness/bundles/general/claude-code/harness-archive/reference.md +1 -1
- package/harness/bundles/general/claude-code/harness-archive/templates/render-summary.mjs +78 -155
- package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +5 -3
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
- package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +6 -2
- package/harness/bundles/general/claude-code/harness-plan/SKILL.md +8 -3
- package/harness/bundles/general/claude-code/harness-review/SKILL.md +8 -3
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +13 -7
- package/harness/bundles/general/claude-code/harness-run/checklist.md +2 -2
- package/harness/bundles/general/claude-code/harness-run/reference.md +6 -3
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +11 -6
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +5 -3
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +12 -3
- package/harness/bundles/general/claude-code/harness-test/reference.md +1 -1
- package/harness/bundles/general/claude-code/protocols/ledger-protocol.md +1 -1
- package/harness/bundles/general/claude-code/protocols/report-pipeline-protocol.md +11 -4
- package/harness/bundles/general/claude-code/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/general/claude-code/scripts/harness_archive.py +231 -48
- package/harness/bundles/general/claude-code/scripts/harness_change.py +854 -0
- package/harness/bundles/general/claude-code/scripts/harness_events.py +134 -40
- package/harness/bundles/general/claude-code/scripts/harness_gate.py +1038 -0
- package/harness/bundles/general/claude-code/scripts/harness_preflight.py +46 -3
- package/harness/bundles/general/claude-code/scripts/harness_profile.py +2 -2
- package/harness/bundles/general/claude-code/scripts/harness_service.py +34 -1
- package/harness/bundles/general/claude-code/scripts/harness_state.py +148 -0
- package/harness/bundles/general/claude-code/scripts/harness_test_guard.py +210 -14
- package/harness/bundles/general/claude-code/scripts/harness_workflow_policy.py +160 -0
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/contracts/workflow-policy.json +169 -0
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +7 -2
- package/harness/bundles/general/codebuddy/harness-archive/reference.md +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/templates/render-summary.mjs +78 -155
- package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +5 -3
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
- package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +6 -2
- package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +8 -3
- package/harness/bundles/general/codebuddy/harness-review/SKILL.md +8 -3
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +13 -7
- package/harness/bundles/general/codebuddy/harness-run/checklist.md +2 -2
- package/harness/bundles/general/codebuddy/harness-run/reference.md +6 -3
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +11 -6
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +5 -3
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +12 -3
- package/harness/bundles/general/codebuddy/harness-test/reference.md +1 -1
- package/harness/bundles/general/codebuddy/protocols/ledger-protocol.md +1 -1
- package/harness/bundles/general/codebuddy/protocols/report-pipeline-protocol.md +11 -4
- package/harness/bundles/general/codebuddy/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/general/codebuddy/scripts/harness_archive.py +231 -48
- package/harness/bundles/general/codebuddy/scripts/harness_change.py +854 -0
- package/harness/bundles/general/codebuddy/scripts/harness_events.py +134 -40
- package/harness/bundles/general/codebuddy/scripts/harness_gate.py +1038 -0
- package/harness/bundles/general/codebuddy/scripts/harness_preflight.py +46 -3
- package/harness/bundles/general/codebuddy/scripts/harness_profile.py +2 -2
- package/harness/bundles/general/codebuddy/scripts/harness_service.py +34 -1
- package/harness/bundles/general/codebuddy/scripts/harness_state.py +148 -0
- package/harness/bundles/general/codebuddy/scripts/harness_test_guard.py +210 -14
- package/harness/bundles/general/codebuddy/scripts/harness_workflow_policy.py +160 -0
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/contracts/workflow-policy.json +169 -0
- package/harness/bundles/general/codex/harness-archive/SKILL.md +7 -2
- package/harness/bundles/general/codex/harness-archive/reference.md +1 -1
- package/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +78 -155
- package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +5 -3
- package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
- package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
- package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +6 -2
- package/harness/bundles/general/codex/harness-plan/SKILL.md +8 -3
- package/harness/bundles/general/codex/harness-review/SKILL.md +7 -2
- package/harness/bundles/general/codex/harness-run/SKILL.md +13 -7
- package/harness/bundles/general/codex/harness-run/checklist.md +2 -2
- package/harness/bundles/general/codex/harness-run/reference.md +6 -3
- package/harness/bundles/general/codex/harness-submit/SKILL.md +11 -6
- package/harness/bundles/general/codex/harness-sync/SKILL.md +5 -3
- package/harness/bundles/general/codex/harness-test/SKILL.md +12 -3
- package/harness/bundles/general/codex/harness-test/reference.md +1 -1
- package/harness/bundles/general/codex/protocols/ledger-protocol.md +1 -1
- package/harness/bundles/general/codex/protocols/report-pipeline-protocol.md +11 -4
- package/harness/bundles/general/codex/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/general/codex/scripts/harness_archive.py +231 -48
- package/harness/bundles/general/codex/scripts/harness_change.py +854 -0
- package/harness/bundles/general/codex/scripts/harness_events.py +134 -40
- package/harness/bundles/general/codex/scripts/harness_gate.py +1038 -0
- package/harness/bundles/general/codex/scripts/harness_preflight.py +46 -3
- package/harness/bundles/general/codex/scripts/harness_profile.py +2 -2
- package/harness/bundles/general/codex/scripts/harness_service.py +34 -1
- package/harness/bundles/general/codex/scripts/harness_state.py +148 -0
- package/harness/bundles/general/codex/scripts/harness_test_guard.py +210 -14
- package/harness/bundles/general/codex/scripts/harness_workflow_policy.py +160 -0
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/contracts/workflow-policy.json +169 -0
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +7 -2
- package/harness/bundles/general/cursor/harness-archive/reference.md +1 -1
- package/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +78 -155
- package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +5 -3
- package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
- package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
- package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +6 -2
- package/harness/bundles/general/cursor/harness-plan/SKILL.md +8 -3
- package/harness/bundles/general/cursor/harness-review/SKILL.md +7 -2
- package/harness/bundles/general/cursor/harness-run/SKILL.md +13 -7
- package/harness/bundles/general/cursor/harness-run/checklist.md +2 -2
- package/harness/bundles/general/cursor/harness-run/reference.md +6 -3
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +11 -6
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +5 -3
- package/harness/bundles/general/cursor/harness-test/SKILL.md +12 -3
- package/harness/bundles/general/cursor/harness-test/reference.md +1 -1
- package/harness/bundles/general/cursor/protocols/ledger-protocol.md +1 -1
- package/harness/bundles/general/cursor/protocols/report-pipeline-protocol.md +11 -4
- package/harness/bundles/general/cursor/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/general/cursor/scripts/harness_archive.py +231 -48
- package/harness/bundles/general/cursor/scripts/harness_change.py +854 -0
- package/harness/bundles/general/cursor/scripts/harness_events.py +134 -40
- package/harness/bundles/general/cursor/scripts/harness_gate.py +1038 -0
- package/harness/bundles/general/cursor/scripts/harness_preflight.py +46 -3
- package/harness/bundles/general/cursor/scripts/harness_profile.py +2 -2
- package/harness/bundles/general/cursor/scripts/harness_service.py +34 -1
- package/harness/bundles/general/cursor/scripts/harness_state.py +148 -0
- package/harness/bundles/general/cursor/scripts/harness_test_guard.py +210 -14
- package/harness/bundles/general/cursor/scripts/harness_workflow_policy.py +160 -0
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/contracts/workflow-policy.json +169 -0
- package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +11 -2
- package/harness/bundles/java/claude-code/harness-archive/SKILL.md +7 -2
- package/harness/bundles/java/claude-code/harness-archive/reference.md +1 -1
- package/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +78 -155
- package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +5 -3
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
- package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +6 -2
- package/harness/bundles/java/claude-code/harness-package/SKILL.md +10 -4
- package/harness/bundles/java/claude-code/harness-plan/SKILL.md +8 -3
- package/harness/bundles/java/claude-code/harness-review/SKILL.md +8 -3
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +13 -7
- package/harness/bundles/java/claude-code/harness-run/reference.md +1 -1
- package/harness/bundles/java/claude-code/harness-submit/SKILL.md +11 -6
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +5 -3
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +12 -3
- package/harness/bundles/java/claude-code/harness-test/reference.md +1 -1
- package/harness/bundles/java/claude-code/protocols/ledger-protocol.md +1 -1
- package/harness/bundles/java/claude-code/protocols/report-pipeline-protocol.md +11 -4
- package/harness/bundles/java/claude-code/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/java/claude-code/scripts/harness_archive.py +231 -48
- package/harness/bundles/java/claude-code/scripts/harness_change.py +854 -0
- package/harness/bundles/java/claude-code/scripts/harness_events.py +134 -40
- package/harness/bundles/java/claude-code/scripts/harness_gate.py +1038 -0
- package/harness/bundles/java/claude-code/scripts/harness_preflight.py +46 -3
- package/harness/bundles/java/claude-code/scripts/harness_profile.py +2 -2
- package/harness/bundles/java/claude-code/scripts/harness_service.py +34 -1
- package/harness/bundles/java/claude-code/scripts/harness_state.py +148 -0
- package/harness/bundles/java/claude-code/scripts/harness_test_guard.py +210 -14
- package/harness/bundles/java/claude-code/scripts/harness_workflow_policy.py +160 -0
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/contracts/workflow-policy.json +169 -0
- package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +11 -2
- package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +7 -2
- package/harness/bundles/java/codebuddy/harness-archive/reference.md +1 -1
- package/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +78 -155
- package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +5 -3
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
- package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +6 -2
- package/harness/bundles/java/codebuddy/harness-package/SKILL.md +10 -4
- package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +8 -3
- package/harness/bundles/java/codebuddy/harness-review/SKILL.md +8 -3
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +13 -7
- package/harness/bundles/java/codebuddy/harness-run/reference.md +1 -1
- package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +11 -6
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +5 -3
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +12 -3
- package/harness/bundles/java/codebuddy/harness-test/reference.md +1 -1
- package/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +1 -1
- package/harness/bundles/java/codebuddy/protocols/report-pipeline-protocol.md +11 -4
- package/harness/bundles/java/codebuddy/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/java/codebuddy/scripts/harness_archive.py +231 -48
- package/harness/bundles/java/codebuddy/scripts/harness_change.py +854 -0
- package/harness/bundles/java/codebuddy/scripts/harness_events.py +134 -40
- package/harness/bundles/java/codebuddy/scripts/harness_gate.py +1038 -0
- package/harness/bundles/java/codebuddy/scripts/harness_preflight.py +46 -3
- package/harness/bundles/java/codebuddy/scripts/harness_profile.py +2 -2
- package/harness/bundles/java/codebuddy/scripts/harness_service.py +34 -1
- package/harness/bundles/java/codebuddy/scripts/harness_state.py +148 -0
- package/harness/bundles/java/codebuddy/scripts/harness_test_guard.py +210 -14
- package/harness/bundles/java/codebuddy/scripts/harness_workflow_policy.py +160 -0
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/contracts/workflow-policy.json +169 -0
- package/harness/bundles/java/codex/harness-apidoc/SKILL.md +11 -2
- package/harness/bundles/java/codex/harness-archive/SKILL.md +7 -2
- package/harness/bundles/java/codex/harness-archive/reference.md +1 -1
- package/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +78 -155
- package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +5 -3
- package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
- package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
- package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +6 -2
- package/harness/bundles/java/codex/harness-package/SKILL.md +10 -4
- package/harness/bundles/java/codex/harness-plan/SKILL.md +8 -3
- package/harness/bundles/java/codex/harness-review/SKILL.md +7 -2
- package/harness/bundles/java/codex/harness-run/SKILL.md +13 -7
- package/harness/bundles/java/codex/harness-run/reference.md +1 -1
- package/harness/bundles/java/codex/harness-submit/SKILL.md +11 -6
- package/harness/bundles/java/codex/harness-sync/SKILL.md +5 -3
- package/harness/bundles/java/codex/harness-test/SKILL.md +12 -3
- package/harness/bundles/java/codex/harness-test/reference.md +1 -1
- package/harness/bundles/java/codex/protocols/ledger-protocol.md +1 -1
- package/harness/bundles/java/codex/protocols/report-pipeline-protocol.md +11 -4
- package/harness/bundles/java/codex/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/java/codex/scripts/harness_archive.py +231 -48
- package/harness/bundles/java/codex/scripts/harness_change.py +854 -0
- package/harness/bundles/java/codex/scripts/harness_events.py +134 -40
- package/harness/bundles/java/codex/scripts/harness_gate.py +1038 -0
- package/harness/bundles/java/codex/scripts/harness_preflight.py +46 -3
- package/harness/bundles/java/codex/scripts/harness_profile.py +2 -2
- package/harness/bundles/java/codex/scripts/harness_service.py +34 -1
- package/harness/bundles/java/codex/scripts/harness_state.py +148 -0
- package/harness/bundles/java/codex/scripts/harness_test_guard.py +210 -14
- package/harness/bundles/java/codex/scripts/harness_workflow_policy.py +160 -0
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/contracts/workflow-policy.json +169 -0
- package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +11 -2
- package/harness/bundles/java/cursor/harness-archive/SKILL.md +7 -2
- package/harness/bundles/java/cursor/harness-archive/reference.md +1 -1
- package/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +78 -155
- package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +4 -2
- package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +5 -3
- package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +109 -7
- package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +2 -0
- package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +6 -2
- package/harness/bundles/java/cursor/harness-package/SKILL.md +10 -4
- package/harness/bundles/java/cursor/harness-plan/SKILL.md +8 -3
- package/harness/bundles/java/cursor/harness-review/SKILL.md +7 -2
- package/harness/bundles/java/cursor/harness-run/SKILL.md +13 -7
- package/harness/bundles/java/cursor/harness-run/reference.md +1 -1
- package/harness/bundles/java/cursor/harness-submit/SKILL.md +11 -6
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +5 -3
- package/harness/bundles/java/cursor/harness-test/SKILL.md +12 -3
- package/harness/bundles/java/cursor/harness-test/reference.md +1 -1
- package/harness/bundles/java/cursor/protocols/ledger-protocol.md +1 -1
- package/harness/bundles/java/cursor/protocols/report-pipeline-protocol.md +11 -4
- package/harness/bundles/java/cursor/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/java/cursor/scripts/harness_archive.py +231 -48
- package/harness/bundles/java/cursor/scripts/harness_change.py +854 -0
- package/harness/bundles/java/cursor/scripts/harness_events.py +134 -40
- package/harness/bundles/java/cursor/scripts/harness_gate.py +1038 -0
- package/harness/bundles/java/cursor/scripts/harness_preflight.py +46 -3
- package/harness/bundles/java/cursor/scripts/harness_profile.py +2 -2
- package/harness/bundles/java/cursor/scripts/harness_service.py +34 -1
- package/harness/bundles/java/cursor/scripts/harness_state.py +148 -0
- package/harness/bundles/java/cursor/scripts/harness_test_guard.py +210 -14
- package/harness/bundles/java/cursor/scripts/harness_workflow_policy.py +160 -0
- package/harness/manifests/general/claude-code.json +48 -28
- package/harness/manifests/general/codebuddy.json +48 -28
- package/harness/manifests/general/codex.json +48 -28
- package/harness/manifests/general/cursor.json +48 -28
- package/harness/manifests/java/claude-code.json +49 -29
- package/harness/manifests/java/codebuddy.json +49 -29
- package/harness/manifests/java/codex.json +49 -29
- package/harness/manifests/java/cursor.json +49 -29
- package/hunter-workflow-family.json +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"riskTiers": {
|
|
4
|
+
"fast": {
|
|
5
|
+
"description": "Low-risk docs/comments/non-behavioral config; no API/DB/security/concurrency.",
|
|
6
|
+
"defaultPhases": ["plan", "run", "submit", "archive"],
|
|
7
|
+
"requiredValidations": ["unitTest"],
|
|
8
|
+
"conditionalStages": ["review", "package", "apidoc"],
|
|
9
|
+
"upgradeTriggers": ["api-change", "security", "migration", "concurrency", "breaking-contract"]
|
|
10
|
+
},
|
|
11
|
+
"standard": {
|
|
12
|
+
"description": "Ordinary production code and non-breaking API/features.",
|
|
13
|
+
"defaultPhases": ["plan", "run", "test", "submit", "archive"],
|
|
14
|
+
"requiredValidations": ["compile", "unitTest", "unitTestFull"],
|
|
15
|
+
"conditionalStages": ["review", "package", "apidoc"],
|
|
16
|
+
"upgradeTriggers": ["auth", "security", "delete", "migration", "concurrency", "artifact-protocol", "shared-state", "breaking-api"]
|
|
17
|
+
},
|
|
18
|
+
"full": {
|
|
19
|
+
"description": "Auth/security/delete/migration/concurrency/service protocol/shared state/breaking contracts.",
|
|
20
|
+
"defaultPhases": ["plan", "run", "test", "review", "submit", "archive"],
|
|
21
|
+
"requiredValidations": ["compile", "unitTest", "unitTestFull", "apiTest"],
|
|
22
|
+
"conditionalStages": ["package", "apidoc"],
|
|
23
|
+
"upgradeTriggers": []
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"skills": {
|
|
27
|
+
"harness-plan": {
|
|
28
|
+
"phase": "plan",
|
|
29
|
+
"inputs": ["requirements", "change-context"],
|
|
30
|
+
"artifacts": ["plans", "spec", "test-scenarios", "implementation-detail"],
|
|
31
|
+
"events": ["phase.start", "phase.end", "decision"],
|
|
32
|
+
"allowedInteractions": [],
|
|
33
|
+
"capabilities": ["risk-classify-plan"]
|
|
34
|
+
},
|
|
35
|
+
"harness-run": {
|
|
36
|
+
"phase": "run",
|
|
37
|
+
"inputs": ["implementation-detail", "state-snapshot"],
|
|
38
|
+
"artifacts": ["code", "verification-ledger"],
|
|
39
|
+
"events": ["phase.start", "phase.end", "command", "verification"],
|
|
40
|
+
"allowedInteractions": [],
|
|
41
|
+
"capabilities": ["gate-begin", "gate-close", "ledger-record"]
|
|
42
|
+
},
|
|
43
|
+
"harness-test": {
|
|
44
|
+
"phase": "test",
|
|
45
|
+
"inputs": ["test-scenarios", "verification-ledger"],
|
|
46
|
+
"artifacts": ["test-reports", "verification-ledger"],
|
|
47
|
+
"events": ["phase.start", "phase.end", "command", "verification"],
|
|
48
|
+
"allowedInteractions": [],
|
|
49
|
+
"capabilities": ["gate-begin", "gate-close", "test-guard", "ledger-record"]
|
|
50
|
+
},
|
|
51
|
+
"harness-review": {
|
|
52
|
+
"phase": "review",
|
|
53
|
+
"inputs": ["diff", "verification-ledger", "test-reports"],
|
|
54
|
+
"artifacts": ["review-report"],
|
|
55
|
+
"events": ["phase.start", "phase.end", "issue", "artifact"],
|
|
56
|
+
"allowedInteractions": [],
|
|
57
|
+
"capabilities": ["gate-begin", "gate-close"]
|
|
58
|
+
},
|
|
59
|
+
"harness-submit": {
|
|
60
|
+
"phase": "submit",
|
|
61
|
+
"inputs": ["verification-ledger", "test-tracking"],
|
|
62
|
+
"artifacts": ["git-integration"],
|
|
63
|
+
"events": ["phase.start", "phase.end", "command", "artifact"],
|
|
64
|
+
"allowedInteractions": ["merge-conflict-resolution"],
|
|
65
|
+
"capabilities": ["gate-begin", "gate-close", "integration-lock", "test-guard-stage"]
|
|
66
|
+
},
|
|
67
|
+
"harness-package": {
|
|
68
|
+
"profiles": ["java"],
|
|
69
|
+
"phase": "package",
|
|
70
|
+
"inputs": ["verification-ledger", "final-commit"],
|
|
71
|
+
"artifacts": ["deploy-artifact"],
|
|
72
|
+
"events": ["phase.start", "phase.end", "command", "verification"],
|
|
73
|
+
"allowedInteractions": [],
|
|
74
|
+
"capabilities": ["gate-begin", "gate-close", "ledger-can-reuse"]
|
|
75
|
+
},
|
|
76
|
+
"harness-archive": {
|
|
77
|
+
"phase": "archive",
|
|
78
|
+
"inputs": ["events", "verification-ledger", "reports"],
|
|
79
|
+
"artifacts": ["summary-data", "archive-manifest"],
|
|
80
|
+
"events": ["phase.start", "phase.end", "artifact"],
|
|
81
|
+
"allowedInteractions": [],
|
|
82
|
+
"capabilities": ["gate-begin", "gate-close"]
|
|
83
|
+
},
|
|
84
|
+
"harness-sync": {
|
|
85
|
+
"phase": "sync",
|
|
86
|
+
"inputs": ["canonical-harness"],
|
|
87
|
+
"artifacts": ["bundle-projection"],
|
|
88
|
+
"events": ["phase.start", "phase.end", "command"],
|
|
89
|
+
"allowedInteractions": [],
|
|
90
|
+
"capabilities": []
|
|
91
|
+
},
|
|
92
|
+
"harness-codebase-map": {
|
|
93
|
+
"phase": "codebase-map",
|
|
94
|
+
"inputs": ["project-root"],
|
|
95
|
+
"artifacts": ["codebase-map"],
|
|
96
|
+
"events": ["phase.start", "phase.end"],
|
|
97
|
+
"allowedInteractions": [],
|
|
98
|
+
"capabilities": []
|
|
99
|
+
},
|
|
100
|
+
"harness-knowledge-query": {
|
|
101
|
+
"phase": "knowledge-query",
|
|
102
|
+
"inputs": ["knowledge-index"],
|
|
103
|
+
"artifacts": [],
|
|
104
|
+
"events": ["phase.start", "phase.end"],
|
|
105
|
+
"allowedInteractions": [],
|
|
106
|
+
"capabilities": ["read-only"]
|
|
107
|
+
},
|
|
108
|
+
"harness-knowledge-ingest": {
|
|
109
|
+
"phase": "knowledge-ingest",
|
|
110
|
+
"inputs": ["archive-evidence"],
|
|
111
|
+
"artifacts": ["knowledge-index"],
|
|
112
|
+
"events": ["phase.start", "phase.end", "command"],
|
|
113
|
+
"allowedInteractions": [],
|
|
114
|
+
"capabilities": []
|
|
115
|
+
},
|
|
116
|
+
"harness-apidoc": {
|
|
117
|
+
"profiles": ["java"],
|
|
118
|
+
"phase": "apidoc",
|
|
119
|
+
"inputs": ["api-diff"],
|
|
120
|
+
"artifacts": ["api-contract-summary"],
|
|
121
|
+
"events": ["phase.start", "phase.end", "artifact"],
|
|
122
|
+
"allowedInteractions": [],
|
|
123
|
+
"capabilities": ["gate-begin", "gate-close"]
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"requiredArtifacts": {
|
|
127
|
+
"plan": ["plans", "spec"],
|
|
128
|
+
"run": [],
|
|
129
|
+
"test": ["tests/test-report-*.md"],
|
|
130
|
+
"review": ["reports/review/review-report-*.md"],
|
|
131
|
+
"submit": [],
|
|
132
|
+
"package": [],
|
|
133
|
+
"archive": ["reports/final/summary-data.json"]
|
|
134
|
+
},
|
|
135
|
+
"requiredValidations": {
|
|
136
|
+
"run": ["compile", "unitTest"],
|
|
137
|
+
"test": ["unitTestFull"],
|
|
138
|
+
"submit": [],
|
|
139
|
+
"package": ["package"]
|
|
140
|
+
},
|
|
141
|
+
"conditionalStages": {
|
|
142
|
+
"review": {
|
|
143
|
+
"tiers": ["standard", "full"],
|
|
144
|
+
"signals": ["security", "auth", "breaking-api", "shared-state"]
|
|
145
|
+
},
|
|
146
|
+
"package": {
|
|
147
|
+
"tiers": ["standard", "full"],
|
|
148
|
+
"signals": ["deploy-required", "install-verification"]
|
|
149
|
+
},
|
|
150
|
+
"apidoc": {
|
|
151
|
+
"tiers": ["standard", "full"],
|
|
152
|
+
"signals": ["api-diff-present"]
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"interactionWhitelist": {
|
|
156
|
+
"global": [],
|
|
157
|
+
"harness-submit": ["merge-conflict-resolution"],
|
|
158
|
+
"harness-plan": ["risk-confirmation"]
|
|
159
|
+
},
|
|
160
|
+
"checkpointRules": {
|
|
161
|
+
"foundation-gate": {
|
|
162
|
+
"afterTasks": [1, 2, 3, 4],
|
|
163
|
+
"beforeTasks": [6, 7, 8, 9, 10],
|
|
164
|
+
"blocking": true,
|
|
165
|
+
"requiredReport": "reports/review/foundation-gate-review.md",
|
|
166
|
+
"reviewerTool": "codex"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -20,7 +20,7 @@ disallowed-tools:
|
|
|
20
20
|
- Bash(awk *)
|
|
21
21
|
- Bash(curl *)
|
|
22
22
|
---
|
|
23
|
-
<!-- generated by harness_deploy.py; core=
|
|
23
|
+
<!-- generated by harness_deploy.py; core=89e664933ed69572; overlay=none; agent=claude-code; do not edit -->
|
|
24
24
|
# harness-archive — 变更归档
|
|
25
25
|
|
|
26
26
|
## Purpose
|
|
@@ -66,11 +66,14 @@ disallowed-tools:
|
|
|
66
66
|
6. **implementation-detail** — 自适应执行参考;legacy 缺失 🟡WARN,不阻断
|
|
67
67
|
7. **test-scenarios** — 测试真相源:`plans/<change>-test-scenarios.md`
|
|
68
68
|
8. **禁止读取 `docs/superpowers/` 作为正式输入** — 旧草稿仅人工线索
|
|
69
|
+
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 变化或缺失时才定向刷新;快照不能替代源码读取和验证门禁。
|
|
69
70
|
|
|
70
71
|
状态目录分层:新路径优先,旧路径兼容 → [[../protocols/state-layout-protocol.md|state-layout-protocol]]
|
|
71
72
|
|
|
72
73
|
## Workflow
|
|
73
74
|
|
|
75
|
+
先用 `harness_change.py resolve [--change] --json` 解析 change;多个 active change 未显式选择时返回 `CHANGE_SELECTION_REQUIRED`,禁止按 Glob/mtime 自动选择。`harness_archive.py finalize` 内部负责且仅负责一次 `harness_gate.py begin` 与 `harness_gate.py close`。调用者禁止重复调用阶段门禁,避免重复事件和幽灵 change 目录。
|
|
76
|
+
|
|
74
77
|
### Phase 0:读取规则和上下文
|
|
75
78
|
|
|
76
79
|
1. 读取本文件。
|
|
@@ -202,7 +205,7 @@ git 命令通过 `powershell.exe -Command "..."` 执行;archive-meta.md 和 fi
|
|
|
202
205
|
|
|
203
206
|
## 执行日志
|
|
204
207
|
|
|
205
|
-
`events.ndjson` 为唯一事实源(schema_version
|
|
208
|
+
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
206
209
|
|
|
207
210
|
```powershell
|
|
208
211
|
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type phase.start --note "<触发指令>"
|
|
@@ -211,3 +214,5 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
211
214
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
212
215
|
|
|
213
216
|
> **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 边界保持最新。
|
|
217
|
+
|
|
218
|
+
每次阶段结束必须写 `--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` 环境变量统一注入。
|
|
@@ -92,4 +92,4 @@ powershell.exe -NoProfile -Command "& '<node-path>' 'harness-skills/harness-arch
|
|
|
92
92
|
|
|
93
93
|
## 执行日志记录
|
|
94
94
|
|
|
95
|
-
归档只向 `events.ndjson` 追加事件(schema_version
|
|
95
|
+
归档只向 `events.ndjson` 追加事件(schema_version 3,兼容读取 v1/v2);`logs/execution-log.md` 由 `harness_events.py append` 自动渲染,禁止手工 Edit。事件类型与脚本用法见 SKILL.md `## 执行日志` 与 `../protocols/report-pipeline-protocol.md`。
|
|
@@ -1,171 +1,94 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// Keeps UTF-8, avoids PowerShell string interpolation issues.
|
|
6
|
-
// All numbers come from summary-data.json or manifest — never re-inferred here.
|
|
7
|
-
|
|
8
|
-
import fs from 'node:fs';
|
|
9
|
-
import path from 'node:path';
|
|
2
|
+
// Compact deterministic renderer for Harness archive summary-data.json.
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
10
5
|
|
|
11
6
|
const args = process.argv.slice(2);
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
return
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const outPath = getArg('--out', args[1] || 'final-summary.html');
|
|
7
|
+
const arg = (name, fallback) => {
|
|
8
|
+
const index = args.indexOf(name);
|
|
9
|
+
return index >= 0 && args[index + 1] ? args[index + 1] : fallback;
|
|
10
|
+
};
|
|
11
|
+
const summaryPath = arg("--summary", args[0]);
|
|
12
|
+
const outPath = arg("--out", args[1] || "final-summary.html");
|
|
19
13
|
if (!summaryPath) {
|
|
20
|
-
console.error(
|
|
14
|
+
console.error("Usage: node render-summary.mjs --summary summary-data.json --out final-summary.html");
|
|
21
15
|
process.exit(2);
|
|
22
16
|
}
|
|
23
17
|
|
|
24
|
-
const data = JSON.parse(fs.readFileSync(summaryPath,
|
|
25
|
-
const esc = (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return
|
|
18
|
+
const data = JSON.parse(fs.readFileSync(summaryPath, "utf8"));
|
|
19
|
+
const esc = (value) => String(value ?? "").replace(/[&<>"']/g, (char) => ({
|
|
20
|
+
"&": "&", "<": "<", ">": ">", '"': """, "'": "'"
|
|
21
|
+
})[char]);
|
|
22
|
+
const list = (value) => Array.isArray(value) ? value : [];
|
|
23
|
+
const record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
24
|
+
const number = (value) => Number(value) || 0;
|
|
25
|
+
const shortHash = (value) => String(value || "N/A").slice(0, 10);
|
|
26
|
+
const statusClass = (value) => {
|
|
27
|
+
const status = String(value || "UNKNOWN").toUpperCase();
|
|
28
|
+
if (/FAIL|ERROR/.test(status)) return "danger";
|
|
29
|
+
if (/WARN|BLOCK|SKIP|CONDITIONAL|PARTIAL|NOT_RUN|UNKNOWN/.test(status)) return "warning";
|
|
30
|
+
if (/ADVISORY|REUSED/.test(status)) return "neutral";
|
|
31
|
+
return "success";
|
|
35
32
|
};
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const m = String(rate).match(/(\d+)\s*\/\s*(\d+)/);
|
|
42
|
-
return m ? { passed: +m[1], total: +m[2] } : null;
|
|
33
|
+
const pill = (value) => `<span class="pill ${statusClass(value)}">${esc(value || "UNKNOWN")}</span>`;
|
|
34
|
+
const describe = (value) => {
|
|
35
|
+
if (typeof value === "string") return value;
|
|
36
|
+
if (!value || typeof value !== "object") return String(value ?? "");
|
|
37
|
+
return value.message || value.action || value.note || value.summary || JSON.stringify(value);
|
|
43
38
|
};
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return `<div class="rate"><div class="bar-track"><div class="bar-fill ${cls}" style="width:${pct}%"></div></div><span class="muted small">${esc(rateStr)} · ${pct}%</span></div>`;
|
|
39
|
+
const duration = (minutes) => {
|
|
40
|
+
const value = number(minutes);
|
|
41
|
+
if (value < 1) return `${Math.round(value * 60)} 秒`;
|
|
42
|
+
if (value < 60) return `${Math.round(value * 10) / 10} 分钟`;
|
|
43
|
+
return `${Math.floor(value / 60)} 小时 ${Math.round(value % 60)} 分钟`;
|
|
50
44
|
};
|
|
51
45
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const diffStat = obj(data.diffStat);
|
|
67
|
-
const changedRows = arr(data.changedFiles).map(f => `<tr><td><code>${esc(f.path || f.file || '')}</code></td><td>${esc(f.summary || f.change || '')}</td><td class="ins">+${esc(f.insertions ?? 0)}</td><td class="del">-${esc(f.deletions ?? 0)}</td></tr>`).join('\n') || `<tr><td colspan="4" class="muted">未记录变更文件</td></tr>`;
|
|
68
|
-
const artifactList = arr(data.artifacts);
|
|
69
|
-
const artifactRows = artifactList.map(a => `<tr><td>${esc(a.name || '')}</td><td><code>${esc(a.path || '')}</code></td><td>${esc(a.size || '')}</td><td><code>${esc(a.sha256 || '')}</code></td></tr>`).join('\n');
|
|
70
|
-
const artifactCard = artifactList.length > 0 ? `<div class="card"><h2>📦 产物清单</h2><table><tr><th>名称</th><th>路径</th><th>大小</th><th>SHA-256</th></tr>${artifactRows}</table></div>` : '';
|
|
71
|
-
const notes = arr(data.maintenanceNotes).map(n => `<li>${esc(n)}</li>`).join('\n') || `<li class="muted">无额外维护说明</li>`;
|
|
72
|
-
const risks = arr(data.knownRisks).map(n => `<li>${esc(n)}</li>`).join('\n') || `<li class="muted">无已知遗留风险</li>`;
|
|
73
|
-
const manual = arr(data.manualActions).map(n => `<li>${esc(n)}</li>`).join('\n') || `<li class="muted">无人工后续动作</li>`;
|
|
74
|
-
const uncommittedList = arr(data.uncommittedTestEvidence);
|
|
75
|
-
const uncommittedTests = uncommittedList.map(n => `<li>${esc(n)}</li>`).join('\n');
|
|
76
|
-
const uncommittedCard = uncommittedList.length > 0 ? `<div class="card"><h2>🧪 未提交测试证据</h2><ul>${uncommittedTests}</ul></div>` : '';
|
|
77
|
-
const review = obj(data.reviewSummary);
|
|
78
|
-
const manifest = obj(data.archiveManifest);
|
|
79
|
-
const timeline = arr(data.timeline).map(t => `<tr><td>${esc(t.stage || '')}</td><td>${badge(t.result || '')}</td><td>${esc(t.evidence || '')}</td></tr>`).join('\n');
|
|
80
|
-
|
|
81
|
-
// durations + skillCalls (schema 2.1); fall back to timeline when absent
|
|
82
|
-
const durations = obj(data.durations);
|
|
83
|
-
const durStages = arr(durations.stages);
|
|
84
|
-
const maxMin = durStages.reduce((m, s) => Math.max(m, num(s.minutes)), 0);
|
|
85
|
-
const durRows = durStages.map(s => {
|
|
86
|
-
const min = num(s.minutes);
|
|
87
|
-
const pct = maxMin > 0 ? Math.round(min / maxMin * 100) : 0;
|
|
88
|
-
return `<div class="dur-row"><div class="dur-label">${esc(s.skill || s.stage || '')} <span class="muted small">${esc(s.result || '')}</span></div><div class="dur-track"><div class="dur-bar" style="width:${pct}%"></div></div><div class="dur-min">${esc(min)}m</div></div>`;
|
|
89
|
-
}).join('\n');
|
|
90
|
-
const skillCallsHtml = arr(data.skillCalls).map(s => `${esc(s.skill)}×${esc(s.count)} ${badge(s.result)}`).join(' ') || '<span class="muted">未记录</span>';
|
|
91
|
-
|
|
92
|
-
const durCard = durStages.length > 0
|
|
93
|
-
? `<div class="card"><h2>⏱️ 阶段耗时与 Skill 调用</h2>${durRows}<div class="muted small" style="margin-top:10px">Skill 调用:${skillCallsHtml}</div></div>`
|
|
94
|
-
: (timeline ? `<div class="card"><h2>阶段时间线</h2><table><tr><th>阶段</th><th>结果</th><th>证据</th></tr>${timeline}</table></div>` : '');
|
|
46
|
+
const stages = Object.entries(record(data.stageStatus));
|
|
47
|
+
const verification = record(data.verification);
|
|
48
|
+
const unit = record(verification.unitTests);
|
|
49
|
+
const api = record(verification.apiTests);
|
|
50
|
+
const durations = record(data.durations);
|
|
51
|
+
const durationStages = list(durations.stages);
|
|
52
|
+
const maxMinutes = Math.max(1, ...durationStages.map((item) => number(item.minutes)));
|
|
53
|
+
const diff = record(data.diffStat);
|
|
54
|
+
const risks = list(data.knownRisks);
|
|
55
|
+
const actions = list(data.manualActions);
|
|
56
|
+
const files = list(data.changedFiles);
|
|
57
|
+
const commands = list(record(data.reportPipeline).commands);
|
|
58
|
+
const timeline = list(data.timeline);
|
|
95
59
|
|
|
96
|
-
const
|
|
60
|
+
const stageHtml = stages.map(([name, status]) => `<div class="row"><span>${esc(name)}</span>${pill(status)}</div>`).join("") || '<p class="empty">没有阶段状态记录</p>';
|
|
61
|
+
const verificationHtml = [
|
|
62
|
+
["单元测试", unit.status || ((number(unit.failures) + number(unit.errors)) > 0 ? "FAIL" : (number(unit.run) > 0 ? "OK" : "NOT_RUN")), `${number(unit.run)} 个 · ${number(unit.failures)} 失败 · ${number(unit.errors)} 错误`],
|
|
63
|
+
["API 测试", api.status || "NOT_RUN", `${number(api.passed)}/${number(api.total)} 通过 · ${number(api.blocked)} 阻塞`],
|
|
64
|
+
["数据库兼容", verification.dbCompatibility || "NOT_RUN", verification.coverageDisplay || "未记录覆盖率"]
|
|
65
|
+
].map(([name, status, note]) => `<div class="row"><div><strong>${esc(name)}</strong><small>${esc(note)}</small></div>${pill(status)}</div>`).join("");
|
|
66
|
+
const durationHtml = durationStages.map((item) => {
|
|
67
|
+
const width = Math.max(2, Math.round(number(item.minutes) / maxMinutes * 100));
|
|
68
|
+
const attempts = list(item.attempts).length;
|
|
69
|
+
return `<div class="duration"><div><span>${esc(item.skill || item.stage)}</span><span>${duration(item.minutes)}${attempts > 1 ? ` · ${attempts} 次尝试` : ""}</span></div><i><b style="width:${width}%"></b></i></div>`;
|
|
70
|
+
}).join("") || '<p class="empty">没有可计算的阶段耗时</p>';
|
|
71
|
+
const riskHtml = risks.map((item) => `<li>${esc(describe(item))}</li>`).join("") || "<li>未记录已知风险</li>";
|
|
72
|
+
const actionHtml = actions.map((item) => `<li>${esc(describe(item))}</li>`).join("") || "<li>无需人工后续动作</li>";
|
|
73
|
+
const fileRows = files.map((item) => `<tr><td><code>${esc(item.path || item.file)}</code></td><td class="plus">+${number(item.insertions)}</td><td class="minus">-${number(item.deletions)}</td></tr>`).join("") || '<tr><td colspan="3">没有变更文件证据</td></tr>';
|
|
74
|
+
const timelineRows = timeline.map((item) => `<tr><td>${esc(item.phase || item.stage || "-")}</td><td>${esc(item.attempt || "-")}</td><td>${pill(item.status || item.result || item.type)}</td><td>${esc(item.executorTool || item.executor_tool || item.summary || "-")}</td></tr>`).join("") || '<tr><td colspan="4">没有时间线记录</td></tr>';
|
|
75
|
+
const commandRows = commands.map((item) => `<tr><td>${esc(item.phase || "-")}</td><td><code>${esc(item.command)}</code></td><td>${pill(number(item.exit_code) === 0 ? "OK" : "FAIL")}</td></tr>`).join("") || '<tr><td colspan="3">没有命令证据</td></tr>';
|
|
97
76
|
|
|
98
|
-
const html = `<!doctype html>
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
h3 { margin: 18px 0 8px; }
|
|
113
|
-
.muted { color: #94a3b8; }
|
|
114
|
-
.small { font-size: 12px; }
|
|
115
|
-
table { width: 100%; border-collapse: collapse; table-layout: fixed; }
|
|
116
|
-
th, td { border-bottom: 1px solid rgba(255,255,255,.12); padding: 10px; text-align: left; vertical-align: top; overflow-wrap: anywhere; }
|
|
117
|
-
th { color: #cbd5e1; font-weight: 600; }
|
|
118
|
-
tbody tr:nth-child(even) { background: rgba(255,255,255,.03); }
|
|
119
|
-
tbody tr:hover { background: rgba(96,165,250,.08); }
|
|
120
|
-
code { color: #bfdbfe; word-break: break-all; }
|
|
121
|
-
.ins { color: #86efac; font-weight: 600; }
|
|
122
|
-
.del { color: #fca5a5; font-weight: 600; }
|
|
123
|
-
.badge { display: inline-block; padding: 4px 8px; border-radius: 999px; font-weight: 700; font-size: 12px; }
|
|
124
|
-
.badge.ok { background: rgba(34,197,94,.16); color: #86efac; }
|
|
125
|
-
.badge.warn { background: rgba(245,158,11,.18); color: #fcd34d; }
|
|
126
|
-
.badge.bad { background: rgba(239,68,68,.18); color: #fca5a5; }
|
|
127
|
-
.badge.info { background: rgba(59,130,246,.18); color: #93c5fd; }
|
|
128
|
-
.grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(200px,1fr)); gap: 16px; }
|
|
129
|
-
.kpi { font-size: 18px; font-weight: 700; margin-top: 4px; word-break: break-all; }
|
|
130
|
-
.hero { border-color: rgba(96,165,250,.35); background: linear-gradient(135deg, rgba(59,130,246,.12), rgba(255,255,255,.04)); }
|
|
131
|
-
ul { margin-top: 8px; }
|
|
132
|
-
.bar-track { background: rgba(255,255,255,.08); border-radius: 999px; height: 8px; overflow: hidden; margin: 4px 0; }
|
|
133
|
-
.bar-fill { height: 100%; border-radius: 999px; }
|
|
134
|
-
.bar-fill.ok { background: #22c55e; }
|
|
135
|
-
.bar-fill.warn { background: #f59e0b; }
|
|
136
|
-
.bar-fill.bad { background: #ef4444; }
|
|
137
|
-
.bar-fill.info { background: #3b82f6; }
|
|
138
|
-
.rate { display: flex; flex-direction: column; gap: 2px; min-width: 160px; }
|
|
139
|
-
.dur-row { display: grid; grid-template-columns: 150px 1fr 50px; align-items: center; gap: 10px; padding: 6px 0; }
|
|
140
|
-
.dur-label { color: #93c5fd; font-size: 13px; }
|
|
141
|
-
.dur-track { background: rgba(255,255,255,.06); border-radius: 4px; height: 18px; overflow: hidden; }
|
|
142
|
-
.dur-bar { height: 100%; background: linear-gradient(90deg, #3b82f6, #60a5fa); border-radius: 4px; }
|
|
143
|
-
.dur-min { color: #94a3b8; font-size: 13px; text-align: right; }
|
|
144
|
-
@media (max-width: 640px) { main { padding: 16px; } .grid { grid-template-columns: 1fr; } .dur-row { grid-template-columns: 100px 1fr 40px; } }
|
|
145
|
-
</style>
|
|
146
|
-
</head>
|
|
147
|
-
<body><main>
|
|
148
|
-
<div class="card hero">
|
|
149
|
-
<h1>变更最终报告:${esc(data.changeName || '')}</h1>
|
|
150
|
-
<p class="muted">${esc(data.businessGoal || '未记录业务目标')}</p>
|
|
151
|
-
</div>
|
|
152
|
-
<div class="grid">
|
|
153
|
-
<div class="card"><div class="muted">🎯 最终状态</div><div class="kpi">${badge(data.finalStatus || data.overallStatus || 'N/A')}</div></div>
|
|
154
|
-
<div class="card"><div class="muted">🔒 Final Commit</div><div class="kpi"><code>${esc(data.finalCommit || 'N/A')}</code></div><div class="muted small">${esc(data.finalCommitBranch || '')}</div></div>
|
|
155
|
-
<div class="card"><div class="muted">📊 代码变更</div><div class="kpi">${esc(diffStat.filesChanged ?? 'N/A')} 文件</div><div class="muted small"><span class="ins">+${esc(diffStat.insertions ?? 0)}</span> <span class="del">-${esc(diffStat.deletions ?? 0)}</span></div></div>
|
|
156
|
-
<div class="card"><div class="muted">⏱️ 总耗时</div><div class="kpi">${esc(totalLabel)}</div><div class="muted small">${esc(durStages.length)} 个阶段</div></div>
|
|
157
|
-
<div class="card"><div class="muted">📝 Review</div><div class="kpi">${esc(review.status || 'N/A')}</div><div class="muted small">RED ${esc(review.red ?? 0)}(修${esc(review.redFixed ?? 0)}/确${esc(review.redConfirmed ?? 0)}) · YEL ${esc(review.yellow ?? 0)}(修${esc(review.yellowFixed ?? 0)}/留${esc(review.yellowDeferred ?? 0)})</div></div>
|
|
158
|
-
<div class="card"><div class="muted">📦 Archive</div><div class="kpi">${esc(manifest.totalArchiveFiles ?? 'N/A')} 文件</div><div class="muted small">${esc(manifest.checksumStatus || 'N/A')}</div></div>
|
|
159
|
-
</div>
|
|
160
|
-
<div class="card"><h2>📋 阶段状态</h2><table><tr><th>阶段</th><th>状态</th></tr>${stageRows}</table></div>
|
|
161
|
-
${durCard}
|
|
162
|
-
<div class="card"><h2>🛡️ 验证明细</h2><table><tr><th>类型</th><th>结果</th></tr>${verificationRows}</table></div>
|
|
163
|
-
<div class="card"><h2>📁 变更文件</h2><table><tr><th>文件</th><th>说明</th><th>+</th><th>-</th></tr>${changedRows}</table></div>
|
|
164
|
-
${artifactCard}
|
|
165
|
-
${uncommittedCard}
|
|
166
|
-
<div class="card"><h2>👨🔧 给后续维护者</h2><ul>${notes}</ul></div>
|
|
167
|
-
<div class="card"><h2>⚠️ 已知风险 / 人工确认项</h2><ul>${risks}</ul><h3>人工后续动作</h3><ul>${manual}</ul></div>
|
|
77
|
+
const html = `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
78
|
+
<title>Harness 最终报告 · ${esc(data.changeName)}</title><style>
|
|
79
|
+
:root{color-scheme:light dark;--bg:#f3f6fa;--card:#fff;--soft:#f7f9fc;--text:#182132;--muted:#667085;--line:#dce3ed;--blue:#2563eb;--good:#087443;--warn:#9b5a00;--bad:#b42318;--shadow:0 8px 24px rgba(18,35,70,.07)}
|
|
80
|
+
@media(prefers-color-scheme:dark){:root{--bg:#0b1018;--card:#121925;--soft:#182130;--text:#eef3fb;--muted:#9aa8bc;--line:#29364a;--blue:#7aa9ff;--good:#55d99d;--warn:#f0bc63;--bad:#ff8b83;--shadow:0 12px 30px rgba(0,0,0,.25)}}
|
|
81
|
+
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:14px/1.5 Inter,"Segoe UI","Microsoft YaHei",sans-serif}main{width:min(1140px,calc(100% - 28px));margin:22px auto 44px}.hero,.card,.metric,details{background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow)}.hero{padding:23px 25px;border-top:3px solid var(--blue)}.eyebrow{color:var(--blue);font-weight:750;letter-spacing:.08em}h1{font-size:27px;line-height:1.2;margin:5px 0 7px;overflow-wrap:anywhere}.goal,.empty,small{color:var(--muted)}.status{display:flex;align-items:center;gap:10px;margin-top:16px}.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:11px;margin:11px 0}.metric{padding:14px 15px}.metric strong{display:block;font-size:19px;margin:4px 0}.grid{display:grid;grid-template-columns:1.12fr .88fr;gap:11px}.card{padding:17px;margin-bottom:11px}h2{font-size:16px;margin:0 0 10px}.row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--line)}.row:last-child{border:0}.row small{display:block;margin-top:2px}.pill{display:inline-flex;border-radius:999px;padding:3px 9px;font-size:11px;font-weight:750;white-space:nowrap}.pill.success{color:var(--good);background:color-mix(in srgb,var(--good) 13%,transparent)}.pill.warning{color:var(--warn);background:color-mix(in srgb,var(--warn) 14%,transparent)}.pill.danger{color:var(--bad);background:color-mix(in srgb,var(--bad) 13%,transparent)}.pill.neutral{color:var(--blue);background:color-mix(in srgb,var(--blue) 12%,transparent)}.duration{margin:11px 0}.duration>div{display:flex;justify-content:space-between;color:var(--muted);font-size:12px}.duration>div span:first-child{color:var(--text);font-weight:650}.duration i{display:block;height:7px;background:var(--soft);border-radius:99px;overflow:hidden;margin-top:6px}.duration b{display:block;height:100%;background:linear-gradient(90deg,var(--blue),#7c70ff)}.risk{display:grid;grid-template-columns:1fr 1fr;gap:10px}.risk>div{background:var(--soft);border-radius:10px;padding:11px}.risk h3{font-size:13px;margin:0 0 5px}.risk ul{padding-left:18px;margin:0;color:var(--muted)}details{margin:9px 0}summary{cursor:pointer;padding:13px 15px;font-weight:650}details>div{padding:0 15px 15px;overflow:auto}table{width:100%;border-collapse:collapse}th,td{text-align:left;padding:8px 9px;border-bottom:1px solid var(--line);vertical-align:top}th{color:var(--muted);font-size:11px;letter-spacing:.04em}code{font-family:"Cascadia Code",Consolas,monospace;color:var(--blue);overflow-wrap:anywhere}.plus{color:var(--good)}.minus{color:var(--bad)}dl{display:grid;grid-template-columns:145px 1fr;gap:7px 11px}dt{color:var(--muted)}dd{margin:0;overflow-wrap:anywhere}
|
|
82
|
+
@media(max-width:800px){.metrics{grid-template-columns:1fr 1fr}.grid,.risk{grid-template-columns:1fr}}@media(max-width:480px){main{width:calc(100% - 18px);margin-top:9px}.metrics{grid-template-columns:1fr}.hero{padding:19px}h1{font-size:23px}dl{grid-template-columns:1fr}}
|
|
83
|
+
</style></head><body><main>
|
|
84
|
+
<section class="hero"><div class="eyebrow">HARNESS EXECUTION REPORT</div><h1>${esc(data.changeName || "未命名变更")}</h1><p class="goal">${esc(data.businessGoal || "未记录业务目标")}</p><div class="status">${pill(data.finalStatus)}<span>基于事件、验证账本与 Git 证据生成</span></div></section>
|
|
85
|
+
<section class="metrics"><article class="metric"><small>任务提交</small><strong><code title="${esc(data.finalCommit)}">${esc(shortHash(data.finalCommit))}</code></strong><small>${esc(data.finalCommitBranch || "未记录分支")}</small></article><article class="metric"><small>代码范围</small><strong>${number(diff.filesChanged)} 个文件</strong><small><span class="plus">+${number(diff.insertions)}</span> · <span class="minus">-${number(diff.deletions)}</span></small></article><article class="metric"><small>总耗时</small><strong>${esc(durations.totalLabel || duration(durations.totalMinutes))}</strong><small>${durationStages.length} 个阶段</small></article><article class="metric"><small>归档完整性</small><strong>${esc(record(data.archiveManifest).checksumStatus || "UNKNOWN")}</strong><small>${number(record(data.archiveManifest).totalArchiveFiles)} 个归档文件</small></article></section>
|
|
86
|
+
<section class="grid"><div><article class="card"><h2>验证结论</h2>${verificationHtml}</article><article class="card"><h2>阶段耗时</h2>${durationHtml}</article></div><div><article class="card"><h2>阶段状态</h2>${stageHtml}</article><article class="card"><h2>风险与后续</h2><div class="risk"><div><h3>已知风险</h3><ul>${riskHtml}</ul></div><div><h3>人工动作</h3><ul>${actionHtml}</ul></div></div></article></div></section>
|
|
87
|
+
<details><summary>变更文件(${files.length})</summary><div><table><thead><tr><th>文件</th><th>新增</th><th>删除</th></tr></thead><tbody>${fileRows}</tbody></table></div></details>
|
|
88
|
+
<details><summary>执行时间线与工具交接(${timeline.length})</summary><div><table><thead><tr><th>阶段</th><th>尝试</th><th>状态</th><th>来源 / 摘要</th></tr></thead><tbody>${timelineRows}</tbody></table></div></details>
|
|
89
|
+
<details><summary>命令证据(${commands.length})</summary><div><table><thead><tr><th>阶段</th><th>命令</th><th>结果</th></tr></thead><tbody>${commandRows}</tbody></table></div></details>
|
|
90
|
+
<details><summary>技术元数据</summary><div><dl><dt>完整提交</dt><dd><code>${esc(data.finalCommit || "N/A")}</code></dd><dt>基线提交</dt><dd><code>${esc(data.baseCommit || "N/A")}</code></dd><dt>Git 范围</dt><dd><code>${esc(diff.range || "N/A")}</code></dd><dt>报告数据版本</dt><dd>${esc(data.schemaVersion || "N/A")}</dd><dt>事实来源</dt><dd>${esc(list(record(data.reportPipeline).sources).join(" · ") || "N/A")}</dd></dl></div></details>
|
|
168
91
|
</main></body></html>`;
|
|
169
92
|
|
|
170
93
|
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
171
|
-
fs.writeFileSync(outPath, html,
|
|
94
|
+
fs.writeFileSync(outPath, html, "utf8");
|
|
@@ -20,7 +20,7 @@ disallowed-tools:
|
|
|
20
20
|
- Bash(awk *)
|
|
21
21
|
- Bash(curl *)
|
|
22
22
|
---
|
|
23
|
-
<!-- generated by harness_deploy.py; core=
|
|
23
|
+
<!-- generated by harness_deploy.py; core=89e664933ed69572; overlay=none; agent=claude-code; do not edit -->
|
|
24
24
|
# harness-codebase-map — 代码库地图
|
|
25
25
|
|
|
26
26
|
## Purpose
|
|
@@ -102,7 +102,7 @@ disallowed-tools:
|
|
|
102
102
|
|
|
103
103
|
## 执行日志
|
|
104
104
|
|
|
105
|
-
`events.ndjson` 为唯一事实源(schema_version
|
|
105
|
+
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
106
106
|
|
|
107
107
|
```powershell
|
|
108
108
|
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type phase.start --note "<触发指令>"
|
|
@@ -111,3 +111,5 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
111
111
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
112
112
|
|
|
113
113
|
> **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 边界保持最新。
|
|
114
|
+
|
|
115
|
+
每次阶段结束必须写 `--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` 环境变量统一注入。
|
|
@@ -20,7 +20,7 @@ disallowed-tools:
|
|
|
20
20
|
- Bash(awk *)
|
|
21
21
|
- Bash(curl *)
|
|
22
22
|
---
|
|
23
|
-
<!-- generated by harness_deploy.py; core=
|
|
23
|
+
<!-- generated by harness_deploy.py; core=89e664933ed69572; overlay=none; agent=claude-code; do not edit -->
|
|
24
24
|
# harness-knowledge-ingest
|
|
25
25
|
|
|
26
26
|
从 `.harness/archive/**/reports/final/summary-data.json` 抽取项目知识,生成并维护本地 `.harness/knowledge/` 索引。
|
|
@@ -236,7 +236,7 @@ powershell.exe -Command "python '<skill-dir>\scripts\harness_knowledge.py' sync
|
|
|
236
236
|
- 当前 `active` / `candidate` / `stale` 数量统计。
|
|
237
237
|
- 产物路径(`index.json`、`index.sqlite`、`views/`、`reports/`)。
|
|
238
238
|
- `lifecycle` 摘要:`validatorsApplied`、`candidateAutoPromoted`、`pendingAgentJudge` 等。
|
|
239
|
-
- **已处理报告**(auto + judge 后):promoted/dropped/superseded/kept/skipped 计数与 `reports/judge-decisions-*.json`、`judgements-*.json`
|
|
239
|
+
- **已处理报告**(auto + judge 后):promoted/dropped/superseded/kept/deferred/skipped 计数与 `reports/judge-decisions-*.json`、`judgements-*.json` 路径;人工判断还会追加到 `judgements/decisions.json`,后续 ingest 不得抹除。`defer` 必须带 `reviewAfter`,到期前不重复进入待判断清单。
|
|
240
240
|
- 仅当 `upToDate=false` 时建议 `sync --update`;查询历史 → `/harness-knowledge-query`。**禁止**默认列出「请人工确认 N 条 candidate」待办。
|
|
241
241
|
|
|
242
242
|
## 渐进披露
|
|
@@ -249,7 +249,7 @@ powershell.exe -Command "python '<skill-dir>\scripts\harness_knowledge.py' sync
|
|
|
249
249
|
|
|
250
250
|
## 执行日志
|
|
251
251
|
|
|
252
|
-
`events.ndjson` 为唯一事实源(schema_version
|
|
252
|
+
`events.ndjson` 为唯一事实源(schema_version 3,兼容读取 v1/v2;`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止用 Write/Edit 直接维护**。直接修改的内容会在 `phase.end` 或 finalize 时被完整重建覆盖,属于数据丢失;需要保留的详情必须进入事件 `note`。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
253
253
|
|
|
254
254
|
```powershell
|
|
255
255
|
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type phase.start --note "<触发指令>"
|
|
@@ -258,3 +258,5 @@ python <skills-root>/scripts/harness_events.py append --change-dir ".harness/cha
|
|
|
258
258
|
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
259
259
|
|
|
260
260
|
> **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 边界保持最新。
|
|
261
|
+
|
|
262
|
+
每次阶段结束必须写 `--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` 环境变量统一注入。
|