@hunter-harness/workflow-harness 0.3.1 → 0.4.1
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/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-archive/reference.md +30 -1
- package/harness/bundles/general/claude-code/harness-archive/templates/summary-data-template.json +1 -0
- package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-execute/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/scripts/harness_archive.py +146 -8
- package/harness/bundles/general/claude-code/scripts/harness_deploy.py +1 -1
- package/harness/bundles/general/claude-code/scripts/harness_knowledge_candidates.py +538 -4
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/reference.md +30 -1
- package/harness/bundles/general/codebuddy/harness-archive/templates/summary-data-template.json +1 -0
- package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-execute/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/scripts/harness_archive.py +146 -8
- package/harness/bundles/general/codebuddy/scripts/harness_deploy.py +1 -1
- package/harness/bundles/general/codebuddy/scripts/harness_knowledge_candidates.py +538 -4
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-archive/reference.md +30 -1
- package/harness/bundles/general/codex/harness-archive/templates/summary-data-template.json +1 -0
- package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-execute/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/codex/scripts/harness_archive.py +146 -8
- package/harness/bundles/general/codex/scripts/harness_deploy.py +1 -1
- package/harness/bundles/general/codex/scripts/harness_knowledge_candidates.py +538 -4
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-archive/reference.md +30 -1
- package/harness/bundles/general/cursor/harness-archive/templates/summary-data-template.json +1 -0
- package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-execute/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-pull/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-push/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/cursor/scripts/harness_archive.py +146 -8
- package/harness/bundles/general/cursor/scripts/harness_deploy.py +1 -1
- package/harness/bundles/general/cursor/scripts/harness_knowledge_candidates.py +538 -4
- package/harness/bundles/general/pi/.harness-build.json +6 -0
- package/harness/bundles/general/pi/CONTEXT.md +98 -0
- package/harness/bundles/general/pi/README.md +478 -0
- package/harness/bundles/general/pi/contracts/build-profile-v3.schema.json +302 -0
- package/harness/bundles/general/pi/contracts/ci-metrics.schema.json +36 -0
- package/harness/bundles/general/pi/contracts/doctor-capability.schema.json +43 -0
- package/harness/bundles/general/pi/contracts/external-platform-observation.schema.json +62 -0
- package/harness/bundles/general/pi/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/general/pi/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/general/pi/contracts/run-session.schema.json +142 -0
- package/harness/bundles/general/pi/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/general/pi/contracts/service-session.schema.json +147 -0
- package/harness/bundles/general/pi/contracts/workflow-policy.json +574 -0
- package/harness/bundles/general/pi/harness-archive/SKILL.md +322 -0
- package/harness/bundles/general/pi/harness-archive/checklist.md +71 -0
- package/harness/bundles/general/pi/harness-archive/reference.md +150 -0
- package/harness/bundles/general/pi/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/harness/bundles/general/pi/harness-archive/templates/summary-data-template.json +218 -0
- package/harness/bundles/general/pi/harness-codebase-map/SKILL.md +116 -0
- package/harness/bundles/general/pi/harness-codebase-map/checklist.md +126 -0
- package/harness/bundles/general/pi/harness-codebase-map/reference.md +364 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/STACK.md +55 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/TESTING.md +64 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/harness/bundles/general/pi/harness-codebase-map/templates/map-summary.md +64 -0
- package/harness/bundles/general/pi/harness-execute/SKILL.md +170 -0
- package/harness/bundles/general/pi/harness-knowledge-ingest/SKILL.md +103 -0
- package/harness/bundles/general/pi/harness-knowledge-query/SKILL.md +97 -0
- package/harness/bundles/general/pi/harness-plan/SKILL.md +158 -0
- package/harness/bundles/general/pi/harness-plan/checklist.md +243 -0
- package/harness/bundles/general/pi/harness-plan/protocols.md +133 -0
- package/harness/bundles/general/pi/harness-plan/reference.md +468 -0
- package/harness/bundles/general/pi/harness-pull/SKILL.md +55 -0
- package/harness/bundles/general/pi/harness-push/SKILL.md +83 -0
- package/harness/bundles/general/pi/harness-review/SKILL.md +175 -0
- package/harness/bundles/general/pi/harness-review/checklist.md +124 -0
- package/harness/bundles/general/pi/harness-review/protocols.md +69 -0
- package/harness/bundles/general/pi/harness-review/reference.md +114 -0
- package/harness/bundles/general/pi/harness-run/SKILL.md +188 -0
- package/harness/bundles/general/pi/harness-run/checklist.md +279 -0
- package/harness/bundles/general/pi/harness-run/protocols.md +141 -0
- package/harness/bundles/general/pi/harness-run/reference.md +886 -0
- package/harness/bundles/general/pi/harness-submit/SKILL.md +182 -0
- package/harness/bundles/general/pi/harness-submit/checklist.md +452 -0
- package/harness/bundles/general/pi/harness-submit/reference.md +152 -0
- package/harness/bundles/general/pi/harness-sync/SKILL.md +72 -0
- package/harness/bundles/general/pi/harness-sync/reference.md +176 -0
- package/harness/bundles/general/pi/harness-test/SKILL.md +250 -0
- package/harness/bundles/general/pi/harness-test/checklist.md +359 -0
- package/harness/bundles/general/pi/harness-test/pitfalls-java.md +14 -0
- package/harness/bundles/general/pi/harness-test/pitfalls.md +307 -0
- package/harness/bundles/general/pi/harness-test/reference.md +880 -0
- package/harness/bundles/general/pi/harness-test/scripts/runtime-helpers.mjs +216 -0
- package/harness/bundles/general/pi/protocols/archive-report-protocol.md +196 -0
- package/harness/bundles/general/pi/protocols/ci-layering-protocol.md +22 -0
- package/harness/bundles/general/pi/protocols/evidence-based-reporting-protocol.md +134 -0
- package/harness/bundles/general/pi/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/general/pi/protocols/external-platform-protocol.md +27 -0
- package/harness/bundles/general/pi/protocols/ledger-protocol.md +365 -0
- package/harness/bundles/general/pi/protocols/memory-closeout-protocol.md +21 -0
- package/harness/bundles/general/pi/protocols/model-routing-protocol.md +22 -0
- package/harness/bundles/general/pi/protocols/powershell-protocol.md +238 -0
- package/harness/bundles/general/pi/protocols/registry-governance-protocol.md +31 -0
- package/harness/bundles/general/pi/protocols/report-pipeline-protocol.md +172 -0
- package/harness/bundles/general/pi/protocols/sensitive-info-protocol.md +110 -0
- package/harness/bundles/general/pi/protocols/state-layout-protocol.md +209 -0
- package/harness/bundles/general/pi/protocols/submit-protocol.md +78 -0
- package/harness/bundles/general/pi/protocols/verification-graph-protocol.md +32 -0
- package/harness/bundles/general/pi/scripts/harness_adoption_metrics.py +391 -0
- package/harness/bundles/general/pi/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/general/pi/scripts/harness_archive.py +11345 -0
- package/harness/bundles/general/pi/scripts/harness_change.py +1626 -0
- package/harness/bundles/general/pi/scripts/harness_check_gate.py +113 -0
- package/harness/bundles/general/pi/scripts/harness_context.py +1774 -0
- package/harness/bundles/general/pi/scripts/harness_deploy.py +968 -0
- package/harness/bundles/general/pi/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/general/pi/scripts/harness_environment.py +1690 -0
- package/harness/bundles/general/pi/scripts/harness_events.py +2234 -0
- package/harness/bundles/general/pi/scripts/harness_events_sync.py +1425 -0
- package/harness/bundles/general/pi/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/general/pi/scripts/harness_fixback.py +1975 -0
- package/harness/bundles/general/pi/scripts/harness_gate.py +3816 -0
- package/harness/bundles/general/pi/scripts/harness_headless.py +37 -0
- package/harness/bundles/general/pi/scripts/harness_integration.py +2564 -0
- package/harness/bundles/general/pi/scripts/harness_knowledge_candidates.py +796 -0
- package/harness/bundles/general/pi/scripts/harness_ledger.py +3556 -0
- package/harness/bundles/general/pi/scripts/harness_migration_head.py +220 -0
- package/harness/bundles/general/pi/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/general/pi/scripts/harness_paths.py +676 -0
- package/harness/bundles/general/pi/scripts/harness_phase.py +1726 -0
- package/harness/bundles/general/pi/scripts/harness_plan_aggregate.py +249 -0
- package/harness/bundles/general/pi/scripts/harness_plan_finalize.py +1016 -0
- package/harness/bundles/general/pi/scripts/harness_preflight.py +650 -0
- package/harness/bundles/general/pi/scripts/harness_process.py +1065 -0
- package/harness/bundles/general/pi/scripts/harness_profile.py +1817 -0
- package/harness/bundles/general/pi/scripts/harness_report_model.py +442 -0
- package/harness/bundles/general/pi/scripts/harness_retry.py +175 -0
- package/harness/bundles/general/pi/scripts/harness_review.py +631 -0
- package/harness/bundles/general/pi/scripts/harness_runtime.py +2243 -0
- package/harness/bundles/general/pi/scripts/harness_service.py +3355 -0
- package/harness/bundles/general/pi/scripts/harness_state.py +365 -0
- package/harness/bundles/general/pi/scripts/harness_sync.py +407 -0
- package/harness/bundles/general/pi/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/general/pi/scripts/harness_test_guard.py +1899 -0
- package/harness/bundles/general/pi/scripts/harness_test_runner.py +1586 -0
- package/harness/bundles/general/pi/scripts/harness_verification.py +593 -0
- package/harness/bundles/general/pi/scripts/harness_workflow_policy.py +266 -0
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-archive/reference.md +30 -1
- package/harness/bundles/java/claude-code/harness-archive/templates/summary-data-template.json +1 -0
- package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-execute/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/scripts/harness_archive.py +146 -8
- package/harness/bundles/java/claude-code/scripts/harness_deploy.py +1 -1
- package/harness/bundles/java/claude-code/scripts/harness_knowledge_candidates.py +538 -4
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-archive/reference.md +30 -1
- package/harness/bundles/java/codebuddy/harness-archive/templates/summary-data-template.json +1 -0
- package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-execute/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/scripts/harness_archive.py +146 -8
- package/harness/bundles/java/codebuddy/scripts/harness_deploy.py +1 -1
- package/harness/bundles/java/codebuddy/scripts/harness_knowledge_candidates.py +538 -4
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-archive/reference.md +30 -1
- package/harness/bundles/java/codex/harness-archive/templates/summary-data-template.json +1 -0
- package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-execute/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/codex/scripts/harness_archive.py +146 -8
- package/harness/bundles/java/codex/scripts/harness_deploy.py +1 -1
- package/harness/bundles/java/codex/scripts/harness_knowledge_candidates.py +538 -4
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-archive/reference.md +30 -1
- package/harness/bundles/java/cursor/harness-archive/templates/summary-data-template.json +1 -0
- package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-execute/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-pull/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-push/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/cursor/scripts/harness_archive.py +146 -8
- package/harness/bundles/java/cursor/scripts/harness_deploy.py +1 -1
- package/harness/bundles/java/cursor/scripts/harness_knowledge_candidates.py +538 -4
- package/harness/bundles/java/pi/.harness-build.json +6 -0
- package/harness/bundles/java/pi/CONTEXT.md +98 -0
- package/harness/bundles/java/pi/README.md +478 -0
- package/harness/bundles/java/pi/contracts/build-profile-v3.schema.json +302 -0
- package/harness/bundles/java/pi/contracts/ci-metrics.schema.json +36 -0
- package/harness/bundles/java/pi/contracts/doctor-capability.schema.json +43 -0
- package/harness/bundles/java/pi/contracts/external-platform-observation.schema.json +62 -0
- package/harness/bundles/java/pi/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/java/pi/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/java/pi/contracts/run-session.schema.json +142 -0
- package/harness/bundles/java/pi/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/java/pi/contracts/service-session.schema.json +147 -0
- package/harness/bundles/java/pi/contracts/workflow-policy.json +574 -0
- package/harness/bundles/java/pi/harness-apidoc/SKILL.md +97 -0
- package/harness/bundles/java/pi/harness-apidoc/checklist.md +142 -0
- package/harness/bundles/java/pi/harness-apidoc/reference.md +233 -0
- package/harness/bundles/java/pi/harness-archive/SKILL.md +322 -0
- package/harness/bundles/java/pi/harness-archive/checklist.md +71 -0
- package/harness/bundles/java/pi/harness-archive/reference.md +150 -0
- package/harness/bundles/java/pi/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/harness/bundles/java/pi/harness-archive/templates/summary-data-template.json +218 -0
- package/harness/bundles/java/pi/harness-codebase-map/SKILL.md +116 -0
- package/harness/bundles/java/pi/harness-codebase-map/checklist.md +126 -0
- package/harness/bundles/java/pi/harness-codebase-map/reference.md +364 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/STACK.md +55 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/TESTING.md +64 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/harness/bundles/java/pi/harness-codebase-map/templates/map-summary.md +64 -0
- package/harness/bundles/java/pi/harness-execute/SKILL.md +170 -0
- package/harness/bundles/java/pi/harness-knowledge-ingest/SKILL.md +103 -0
- package/harness/bundles/java/pi/harness-knowledge-query/SKILL.md +97 -0
- package/harness/bundles/java/pi/harness-package/SKILL.md +94 -0
- package/harness/bundles/java/pi/harness-package/checklist.md +322 -0
- package/harness/bundles/java/pi/harness-package/reference.md +210 -0
- package/harness/bundles/java/pi/harness-plan/SKILL.md +158 -0
- package/harness/bundles/java/pi/harness-plan/checklist.md +243 -0
- package/harness/bundles/java/pi/harness-plan/protocols.md +133 -0
- package/harness/bundles/java/pi/harness-plan/reference.md +468 -0
- package/harness/bundles/java/pi/harness-pull/SKILL.md +55 -0
- package/harness/bundles/java/pi/harness-push/SKILL.md +83 -0
- package/harness/bundles/java/pi/harness-review/SKILL.md +175 -0
- package/harness/bundles/java/pi/harness-review/checklist.md +124 -0
- package/harness/bundles/java/pi/harness-review/protocols.md +69 -0
- package/harness/bundles/java/pi/harness-review/reference.md +114 -0
- package/harness/bundles/java/pi/harness-run/SKILL.md +206 -0
- package/harness/bundles/java/pi/harness-run/checklist.md +252 -0
- package/harness/bundles/java/pi/harness-run/protocols.md +141 -0
- package/harness/bundles/java/pi/harness-run/reference.md +820 -0
- package/harness/bundles/java/pi/harness-submit/SKILL.md +189 -0
- package/harness/bundles/java/pi/harness-submit/checklist.md +452 -0
- package/harness/bundles/java/pi/harness-submit/reference.md +152 -0
- package/harness/bundles/java/pi/harness-sync/SKILL.md +72 -0
- package/harness/bundles/java/pi/harness-sync/reference.md +176 -0
- package/harness/bundles/java/pi/harness-test/SKILL.md +264 -0
- package/harness/bundles/java/pi/harness-test/checklist.md +320 -0
- package/harness/bundles/java/pi/harness-test/pitfalls-java.md +16 -0
- package/harness/bundles/java/pi/harness-test/pitfalls.md +307 -0
- package/harness/bundles/java/pi/harness-test/reference.md +792 -0
- package/harness/bundles/java/pi/harness-test/scripts/runtime-helpers.mjs +216 -0
- package/harness/bundles/java/pi/protocols/archive-report-protocol.md +196 -0
- package/harness/bundles/java/pi/protocols/ci-layering-protocol.md +22 -0
- package/harness/bundles/java/pi/protocols/evidence-based-reporting-protocol.md +134 -0
- package/harness/bundles/java/pi/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/java/pi/protocols/external-platform-protocol.md +27 -0
- package/harness/bundles/java/pi/protocols/ledger-protocol.md +365 -0
- package/harness/bundles/java/pi/protocols/memory-closeout-protocol.md +21 -0
- package/harness/bundles/java/pi/protocols/model-routing-protocol.md +22 -0
- package/harness/bundles/java/pi/protocols/powershell-protocol.md +238 -0
- package/harness/bundles/java/pi/protocols/registry-governance-protocol.md +31 -0
- package/harness/bundles/java/pi/protocols/report-pipeline-protocol.md +172 -0
- package/harness/bundles/java/pi/protocols/sensitive-info-protocol.md +110 -0
- package/harness/bundles/java/pi/protocols/state-layout-protocol.md +209 -0
- package/harness/bundles/java/pi/protocols/submit-protocol.md +78 -0
- package/harness/bundles/java/pi/protocols/verification-graph-protocol.md +32 -0
- package/harness/bundles/java/pi/scripts/harness_adoption_metrics.py +391 -0
- package/harness/bundles/java/pi/scripts/harness_apidoc.py +53 -0
- package/harness/bundles/java/pi/scripts/harness_archive.py +11345 -0
- package/harness/bundles/java/pi/scripts/harness_change.py +1626 -0
- package/harness/bundles/java/pi/scripts/harness_check_gate.py +113 -0
- package/harness/bundles/java/pi/scripts/harness_context.py +1774 -0
- package/harness/bundles/java/pi/scripts/harness_deploy.py +968 -0
- package/harness/bundles/java/pi/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/java/pi/scripts/harness_environment.py +1690 -0
- package/harness/bundles/java/pi/scripts/harness_events.py +2234 -0
- package/harness/bundles/java/pi/scripts/harness_events_sync.py +1425 -0
- package/harness/bundles/java/pi/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/java/pi/scripts/harness_fixback.py +1975 -0
- package/harness/bundles/java/pi/scripts/harness_gate.py +3816 -0
- package/harness/bundles/java/pi/scripts/harness_headless.py +37 -0
- package/harness/bundles/java/pi/scripts/harness_integration.py +2564 -0
- package/harness/bundles/java/pi/scripts/harness_knowledge_candidates.py +796 -0
- package/harness/bundles/java/pi/scripts/harness_ledger.py +3556 -0
- package/harness/bundles/java/pi/scripts/harness_migration_head.py +220 -0
- package/harness/bundles/java/pi/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/java/pi/scripts/harness_paths.py +676 -0
- package/harness/bundles/java/pi/scripts/harness_phase.py +1726 -0
- package/harness/bundles/java/pi/scripts/harness_plan_aggregate.py +249 -0
- package/harness/bundles/java/pi/scripts/harness_plan_finalize.py +1016 -0
- package/harness/bundles/java/pi/scripts/harness_preflight.py +650 -0
- package/harness/bundles/java/pi/scripts/harness_process.py +1065 -0
- package/harness/bundles/java/pi/scripts/harness_profile.py +1817 -0
- package/harness/bundles/java/pi/scripts/harness_report_model.py +442 -0
- package/harness/bundles/java/pi/scripts/harness_retry.py +175 -0
- package/harness/bundles/java/pi/scripts/harness_review.py +631 -0
- package/harness/bundles/java/pi/scripts/harness_runtime.py +2243 -0
- package/harness/bundles/java/pi/scripts/harness_service.py +3355 -0
- package/harness/bundles/java/pi/scripts/harness_state.py +365 -0
- package/harness/bundles/java/pi/scripts/harness_sync.py +407 -0
- package/harness/bundles/java/pi/scripts/harness_test_cleanup.py +175 -0
- package/harness/bundles/java/pi/scripts/harness_test_guard.py +1899 -0
- package/harness/bundles/java/pi/scripts/harness_test_runner.py +1586 -0
- package/harness/bundles/java/pi/scripts/harness_verification.py +593 -0
- package/harness/bundles/java/pi/scripts/harness_workflow_policy.py +266 -0
- package/harness/manifests/general/claude-code.json +19 -19
- package/harness/manifests/general/codebuddy.json +19 -19
- package/harness/manifests/general/codex.json +19 -19
- package/harness/manifests/general/cursor.json +19 -19
- package/harness/manifests/general/pi.json +475 -0
- package/harness/manifests/java/claude-code.json +21 -21
- package/harness/manifests/java/codebuddy.json +21 -21
- package/harness/manifests/java/codex.json +21 -21
- package/harness/manifests/java/cursor.json +21 -21
- package/harness/manifests/java/pi.json +499 -0
- package/hunter-workflow-family.json +2 -2
- package/package.json +1 -1
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
"""Knowledge candidate generation from an archived change's summary-data.json.
|
|
3
3
|
|
|
4
4
|
The archive workflow has already filtered once: review findings were produced by
|
|
5
|
-
an independent reviewer and then adjudicated,
|
|
6
|
-
facts
|
|
7
|
-
|
|
5
|
+
an independent reviewer and then adjudicated, knownRisks are evidence-derived
|
|
6
|
+
facts, and decisions are structured records adopted upstream (plan/execute/
|
|
7
|
+
review). This module turns those three — and only those three — into
|
|
8
|
+
KnowledgeCandidate records for the archive package's ``candidates/knowledge.json``.
|
|
8
9
|
|
|
9
10
|
Mapping is fixed by docs/superpowers/specs/2026-08-18-three-views-data-flow-design.md
|
|
10
|
-
("知识来源的选定")::
|
|
11
|
+
("知识来源的选定"), extended 2026-08-23 with the decisions source::
|
|
11
12
|
|
|
12
13
|
disposition = FIXED -> pitfall RED 0.95 / YELLOW 0.85
|
|
13
14
|
disposition = ACCEPTED_RISK | DEFERRED -> risk RED 0.95 / YELLOW 0.85
|
|
14
15
|
knownRisks[] -> risk 0.85
|
|
16
|
+
decisions[status=adopted] -> record's entry_type (decision |
|
|
17
|
+
requirement | api-contract) 0.85
|
|
15
18
|
severity = OK | disposition = NOT_APPLICABLE -> dropped
|
|
19
|
+
decisions[status != adopted] -> kept in summary, not knowledge
|
|
16
20
|
|
|
17
21
|
Dispositions outside the adopted set (OPEN / UNKNOWN) are dropped too: an
|
|
18
22
|
unadjudicated finding is not yet knowledge. maintenanceNotes, finalStatusReasons
|
|
@@ -42,6 +46,16 @@ _DISPOSITION_ENTRY_TYPES = {
|
|
|
42
46
|
_SEVERITY_CONFIDENCE = {"RED": 0.95, "YELLOW": 0.85}
|
|
43
47
|
_KNOWN_RISK_CONFIDENCE = 0.85
|
|
44
48
|
|
|
49
|
+
# decisions[](来自 change 的 evidence/decisions.json,经 summary.decisions 传入)
|
|
50
|
+
# 与 findings 的裁决门槛同源:只有已采纳(adopted)的决策才成为候选——
|
|
51
|
+
# proposed/rejected/superseded 留在 summary 里做记录,但不构成知识。
|
|
52
|
+
# entry_type 直接取自记录,取值与 knowledgeCandidateEntryTypeSchema 对齐;
|
|
53
|
+
# source 对应 candidateProvenanceSourceKindSchema 的枚举。
|
|
54
|
+
_DECISION_ENTRY_TYPES = {"decision", "requirement", "api-contract"}
|
|
55
|
+
_DECISION_STATUSES = {"adopted", "proposed", "rejected", "superseded"}
|
|
56
|
+
_DECISION_SOURCE_KINDS = {"plan", "review", "manual", "archive"}
|
|
57
|
+
_DECISION_CONFIDENCE = 0.85
|
|
58
|
+
|
|
45
59
|
_MAX_KEYWORDS = 32
|
|
46
60
|
_MAX_KEYWORD_CHARS = 80
|
|
47
61
|
_MAX_BODY_CHARS = 20_000
|
|
@@ -204,6 +218,86 @@ def _risk_candidate(
|
|
|
204
218
|
}
|
|
205
219
|
|
|
206
220
|
|
|
221
|
+
def _decision_candidate(
|
|
222
|
+
record: dict[str, Any],
|
|
223
|
+
*,
|
|
224
|
+
change_key: str,
|
|
225
|
+
archive_id: str,
|
|
226
|
+
producer_version: str,
|
|
227
|
+
created_at: str,
|
|
228
|
+
) -> dict[str, Any] | None:
|
|
229
|
+
"""Project one adopted design decision / requirement / API contract entry.
|
|
230
|
+
|
|
231
|
+
Every field is copied from the record (written upstream by a human or an
|
|
232
|
+
agent during plan/execute/review); nothing is inferred at archive time.
|
|
233
|
+
"""
|
|
234
|
+
title = _text(record.get("title"))
|
|
235
|
+
entry_type = _text(record.get("entry_type"))
|
|
236
|
+
status = _text(record.get("status")).lower()
|
|
237
|
+
if not title or entry_type not in _DECISION_ENTRY_TYPES or status != "adopted":
|
|
238
|
+
return None
|
|
239
|
+
|
|
240
|
+
rationale = _text(record.get("rationale"))
|
|
241
|
+
path = _text(record.get("path"))
|
|
242
|
+
line = record.get("line")
|
|
243
|
+
location = _location(path, line)
|
|
244
|
+
segments = _path_segments(path)
|
|
245
|
+
record_id = _text(record.get("id"))
|
|
246
|
+
source = _text(record.get("source"))
|
|
247
|
+
if source not in _DECISION_SOURCE_KINDS:
|
|
248
|
+
source = "plan"
|
|
249
|
+
raw_keywords = record.get("keywords")
|
|
250
|
+
record_keywords = (
|
|
251
|
+
[item for item in raw_keywords if isinstance(item, str)]
|
|
252
|
+
if isinstance(raw_keywords, list)
|
|
253
|
+
else []
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
body_lines = [title]
|
|
257
|
+
if rationale:
|
|
258
|
+
body_lines.append(f"理由:{rationale}")
|
|
259
|
+
if location:
|
|
260
|
+
body_lines.append(f"位置:{location}")
|
|
261
|
+
body_lines.append(f"类型:{entry_type}")
|
|
262
|
+
body = "\n".join(body_lines)[:_MAX_BODY_CHARS]
|
|
263
|
+
keywords = _keywords(
|
|
264
|
+
*record_keywords,
|
|
265
|
+
segments[-1] if segments else "",
|
|
266
|
+
segments[-2] if len(segments) >= 2 else "",
|
|
267
|
+
entry_type,
|
|
268
|
+
)
|
|
269
|
+
if path and location != path:
|
|
270
|
+
source_refs = [f"{path}#L{line}"]
|
|
271
|
+
elif path:
|
|
272
|
+
source_refs = [path]
|
|
273
|
+
else:
|
|
274
|
+
source_refs = [f"archive:{archive_id}"]
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
"schema_version": SCHEMA_VERSION,
|
|
278
|
+
"candidate_id": _candidate_id(
|
|
279
|
+
change_key, "decision", record_id or f"{title}\0{path}\0{line}"
|
|
280
|
+
),
|
|
281
|
+
"source_change_key": change_key,
|
|
282
|
+
"source_refs": source_refs,
|
|
283
|
+
"summary": title,
|
|
284
|
+
"reusability_scope": segments[0] if segments else "project",
|
|
285
|
+
"content_hash": _content_hash(entry_type, title, body, keywords),
|
|
286
|
+
"confidence": _DECISION_CONFIDENCE,
|
|
287
|
+
"status": "pending",
|
|
288
|
+
"entry_type": entry_type,
|
|
289
|
+
"body": body,
|
|
290
|
+
"keywords": keywords,
|
|
291
|
+
"provenance": {
|
|
292
|
+
"source_kind": source,
|
|
293
|
+
"source_ref": f"archive:{archive_id}#{record_id}" if record_id else f"archive:{archive_id}",
|
|
294
|
+
"producer": PRODUCER,
|
|
295
|
+
"producer_version": producer_version,
|
|
296
|
+
"created_at": created_at,
|
|
297
|
+
},
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
207
301
|
def build_knowledge_candidates(
|
|
208
302
|
summary: dict[str, Any],
|
|
209
303
|
*,
|
|
@@ -252,6 +346,446 @@ def build_knowledge_candidates(
|
|
|
252
346
|
created_at=created_at,
|
|
253
347
|
))
|
|
254
348
|
|
|
349
|
+
decisions = summary.get("decisions")
|
|
350
|
+
if isinstance(decisions, list):
|
|
351
|
+
for record in decisions:
|
|
352
|
+
if isinstance(record, dict):
|
|
353
|
+
collect(_decision_candidate(
|
|
354
|
+
record,
|
|
355
|
+
change_key=change_key,
|
|
356
|
+
archive_id=archive_id,
|
|
357
|
+
producer_version=producer_version,
|
|
358
|
+
created_at=created_at,
|
|
359
|
+
))
|
|
360
|
+
|
|
361
|
+
return candidates
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
# Dispositions that mean "not yet adjudicated". A finding in this state with a
|
|
365
|
+
# knowledge-carrying severity is dropped by the mapping above — correctly — but
|
|
366
|
+
# the drop must be visible, or an archive with real findings looks identical to
|
|
367
|
+
# an archive with nothing worth keeping (both ship an empty candidates file).
|
|
368
|
+
_UNADJUDICATED_DISPOSITIONS = {"", "OPEN", "UNKNOWN"}
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def count_unadjudicated_findings(summary: dict[str, Any]) -> int:
|
|
372
|
+
"""Count RED/YELLOW reviewFindings whose disposition is not yet adjudicated.
|
|
373
|
+
|
|
374
|
+
These are the findings the mapping table silently drops. Callers use the
|
|
375
|
+
count to warn when an archive would otherwise show "ready / 0 results"
|
|
376
|
+
despite carrying real, unprocessed review signal.
|
|
377
|
+
"""
|
|
378
|
+
if not isinstance(summary, dict):
|
|
379
|
+
return 0
|
|
380
|
+
findings = summary.get("reviewFindings")
|
|
381
|
+
if not isinstance(findings, list):
|
|
382
|
+
return 0
|
|
383
|
+
count = 0
|
|
384
|
+
for finding in findings:
|
|
385
|
+
if not isinstance(finding, dict):
|
|
386
|
+
continue
|
|
387
|
+
severity = _text(finding.get("severity"))
|
|
388
|
+
disposition = _text(finding.get("disposition")).upper()
|
|
389
|
+
if severity in _SEVERITIES and disposition in _UNADJUDICATED_DISPOSITIONS:
|
|
390
|
+
count += 1
|
|
391
|
+
return count
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
# --- plan/design-derived knowledge candidates ---------------------------------
|
|
395
|
+
#
|
|
396
|
+
# reviewFindings/knownRisks/decisions 只覆盖“经对抗评审的变更”。没有评审的简单
|
|
397
|
+
# 变更(无 RED/YELLOW 发现、无 knownRisks、无 adopted decisions)仍产出了
|
|
398
|
+
# 经用户确认批准的 design/plan/test-scenarios——这些也是值得沉淀的知识。
|
|
399
|
+
# 这里把 plans/*.md(v2 finalize 派生的机器契约)解析回结构化的自然内容,
|
|
400
|
+
# 与 summary 三源并列,但 confidence 略低(机器派生而非独立评审)。
|
|
401
|
+
|
|
402
|
+
_PLAN_CONFIDENCE = 0.85
|
|
403
|
+
_PLAN_SOURCE_KIND = "plan"
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def _unescape_markdown(value: str) -> str:
|
|
407
|
+
"""Reverse the renderer's markdown escaping for clean knowledge text.
|
|
408
|
+
|
|
409
|
+
harness-plan finalize 的渲染器对自由文本做了反斜杠/实体转义。知识候选存
|
|
410
|
+
的是自然语言,不需要保留渲染转义。顺序有讲究:先反转义实体,再反转义
|
|
411
|
+
反斜杠序列(从长到短)。
|
|
412
|
+
"""
|
|
413
|
+
value = (
|
|
414
|
+
value.replace("<", "<")
|
|
415
|
+
.replace(">", ">")
|
|
416
|
+
.replace("&", "&")
|
|
417
|
+
.replace("<br>", "\n")
|
|
418
|
+
)
|
|
419
|
+
return (
|
|
420
|
+
value.replace("\\`", "`")
|
|
421
|
+
.replace("\\#", "#")
|
|
422
|
+
.replace("\\*", "*")
|
|
423
|
+
.replace("\\[", "[")
|
|
424
|
+
.replace("\\]", "]")
|
|
425
|
+
.replace("\\\\", "\\")
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def _markdown_sections(text: str) -> dict[str, list[str]]:
|
|
430
|
+
"""Split a v2 rendered markdown artifact into its ``## Header`` sections.
|
|
431
|
+
|
|
432
|
+
Returns ``{header: [lines...]}``. Only the ``##`` level is split; ``###``
|
|
433
|
+
and ``####`` content stays inside its parent section's lines.
|
|
434
|
+
"""
|
|
435
|
+
sections: dict[str, list[str]] = {}
|
|
436
|
+
current: str | None = None
|
|
437
|
+
for line in text.splitlines():
|
|
438
|
+
if line.startswith("## ") and not line.startswith("### "):
|
|
439
|
+
current = line[3:].strip()
|
|
440
|
+
sections[current] = []
|
|
441
|
+
elif current is not None:
|
|
442
|
+
sections[current].append(line)
|
|
443
|
+
return sections
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def _plan_source_refs(change_key: str, package_path: str) -> list[str]:
|
|
447
|
+
"""source_refs must exist in the package (core-v1 containment check)."""
|
|
448
|
+
return [package_path]
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def _plan_candidate(
|
|
452
|
+
*,
|
|
453
|
+
change_key: str,
|
|
454
|
+
archive_id: str,
|
|
455
|
+
producer_version: str,
|
|
456
|
+
created_at: str,
|
|
457
|
+
kind: str,
|
|
458
|
+
entry_type: str,
|
|
459
|
+
summary: str,
|
|
460
|
+
body: str,
|
|
461
|
+
keywords: list[str],
|
|
462
|
+
source_refs: list[str],
|
|
463
|
+
reusability_scope: str = "project",
|
|
464
|
+
) -> dict[str, Any]:
|
|
465
|
+
return {
|
|
466
|
+
"schema_version": SCHEMA_VERSION,
|
|
467
|
+
"candidate_id": _candidate_id(change_key, kind, summary),
|
|
468
|
+
"source_change_key": change_key,
|
|
469
|
+
"source_refs": source_refs,
|
|
470
|
+
"summary": summary,
|
|
471
|
+
"reusability_scope": reusability_scope,
|
|
472
|
+
"content_hash": _content_hash(entry_type, summary, body, keywords),
|
|
473
|
+
"confidence": _PLAN_CONFIDENCE,
|
|
474
|
+
"status": "pending",
|
|
475
|
+
"entry_type": entry_type,
|
|
476
|
+
"body": body,
|
|
477
|
+
"keywords": keywords,
|
|
478
|
+
"provenance": {
|
|
479
|
+
"source_kind": _PLAN_SOURCE_KIND,
|
|
480
|
+
"source_ref": f"archive:{archive_id}",
|
|
481
|
+
"producer": PRODUCER,
|
|
482
|
+
"producer_version": producer_version,
|
|
483
|
+
"created_at": created_at,
|
|
484
|
+
},
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
def _requirements_from_design(
|
|
489
|
+
design_text: str,
|
|
490
|
+
*,
|
|
491
|
+
change_key: str,
|
|
492
|
+
archive_id: str,
|
|
493
|
+
producer_version: str,
|
|
494
|
+
created_at: str,
|
|
495
|
+
) -> list[dict[str, Any]]:
|
|
496
|
+
"""Parse ``## Requirements`` from design.md into requirement candidates.
|
|
497
|
+
|
|
498
|
+
Each line is ``- requirement:sha256:... [kind]: text`` where kind is
|
|
499
|
+
behavior | invariant | failure_behavior.
|
|
500
|
+
"""
|
|
501
|
+
sections = _markdown_sections(design_text)
|
|
502
|
+
lines = sections.get("Requirements", [])
|
|
503
|
+
out: list[dict[str, Any]] = []
|
|
504
|
+
for line in lines:
|
|
505
|
+
stripped = line.strip()
|
|
506
|
+
if not stripped.startswith("- "):
|
|
507
|
+
continue
|
|
508
|
+
prefix = stripped[2:]
|
|
509
|
+
# kind 位于第一个 `]: ` 之前的方括号内。
|
|
510
|
+
close_bracket = prefix.find("]")
|
|
511
|
+
if close_bracket <= 0 or not prefix.startswith("requirement:"):
|
|
512
|
+
continue
|
|
513
|
+
kind = prefix[1:close_bracket].strip()
|
|
514
|
+
if kind not in {"behavior", "invariant", "failure_behavior"}:
|
|
515
|
+
continue
|
|
516
|
+
colon = prefix.find(": ", close_bracket + 1)
|
|
517
|
+
if colon == -1:
|
|
518
|
+
continue
|
|
519
|
+
text = _unescape_markdown(prefix[colon + 2:].strip())
|
|
520
|
+
if not text:
|
|
521
|
+
continue
|
|
522
|
+
entry_type = "requirement"
|
|
523
|
+
body = f"需求类型:{kind}\n{text}"
|
|
524
|
+
keywords = _keywords(kind, entry_type)
|
|
525
|
+
out.append(_plan_candidate(
|
|
526
|
+
change_key=change_key,
|
|
527
|
+
archive_id=archive_id,
|
|
528
|
+
producer_version=producer_version,
|
|
529
|
+
created_at=created_at,
|
|
530
|
+
kind="requirement",
|
|
531
|
+
entry_type=entry_type,
|
|
532
|
+
summary=text,
|
|
533
|
+
body=body,
|
|
534
|
+
keywords=keywords,
|
|
535
|
+
source_refs=_plan_source_refs(change_key, f"plans/{change_key}-design.md"),
|
|
536
|
+
))
|
|
537
|
+
return out
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
def _risks_from_design(
|
|
541
|
+
design_text: str,
|
|
542
|
+
*,
|
|
543
|
+
change_key: str,
|
|
544
|
+
archive_id: str,
|
|
545
|
+
producer_version: str,
|
|
546
|
+
created_at: str,
|
|
547
|
+
) -> list[dict[str, Any]]:
|
|
548
|
+
"""Parse ``## Risks`` (``- risk`` + `` - Mitigation: ...``) into risk candidates."""
|
|
549
|
+
sections = _markdown_sections(design_text)
|
|
550
|
+
lines = sections.get("Risks", [])
|
|
551
|
+
out: list[dict[str, Any]] = []
|
|
552
|
+
index = 0
|
|
553
|
+
while index < len(lines):
|
|
554
|
+
stripped = lines[index].strip()
|
|
555
|
+
if not stripped.startswith("- "):
|
|
556
|
+
index += 1
|
|
557
|
+
continue
|
|
558
|
+
risk = _unescape_markdown(stripped[2:].strip())
|
|
559
|
+
if not risk or risk == "None.":
|
|
560
|
+
index += 1
|
|
561
|
+
continue
|
|
562
|
+
mitigation = ""
|
|
563
|
+
if index + 1 < len(lines) and lines[index + 1].strip().startswith("- Mitigation:"):
|
|
564
|
+
mitigation = _unescape_markdown(
|
|
565
|
+
lines[index + 1].strip()[len("- Mitigation:"):].strip()
|
|
566
|
+
)
|
|
567
|
+
index += 1
|
|
568
|
+
body = risk if not mitigation else f"{risk}\n缓解:{mitigation}"
|
|
569
|
+
out.append(_plan_candidate(
|
|
570
|
+
change_key=change_key,
|
|
571
|
+
archive_id=archive_id,
|
|
572
|
+
producer_version=producer_version,
|
|
573
|
+
created_at=created_at,
|
|
574
|
+
kind="risk",
|
|
575
|
+
entry_type="risk",
|
|
576
|
+
summary=risk,
|
|
577
|
+
body=body,
|
|
578
|
+
keywords=_keywords("risk"),
|
|
579
|
+
source_refs=_plan_source_refs(change_key, f"plans/{change_key}-design.md"),
|
|
580
|
+
))
|
|
581
|
+
index += 1
|
|
582
|
+
return out
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
def _invariants_from_design(
|
|
586
|
+
design_text: str,
|
|
587
|
+
*,
|
|
588
|
+
change_key: str,
|
|
589
|
+
archive_id: str,
|
|
590
|
+
producer_version: str,
|
|
591
|
+
created_at: str,
|
|
592
|
+
) -> list[dict[str, Any]]:
|
|
593
|
+
"""Parse ``## Invariants`` bullet list into requirement candidates."""
|
|
594
|
+
sections = _markdown_sections(design_text)
|
|
595
|
+
out: list[dict[str, Any]] = []
|
|
596
|
+
for line in sections.get("Invariants", []):
|
|
597
|
+
stripped = line.strip()
|
|
598
|
+
if not stripped.startswith("- "):
|
|
599
|
+
continue
|
|
600
|
+
text = _unescape_markdown(stripped[2:].strip())
|
|
601
|
+
if not text or text == "None.":
|
|
602
|
+
continue
|
|
603
|
+
out.append(_plan_candidate(
|
|
604
|
+
change_key=change_key,
|
|
605
|
+
archive_id=archive_id,
|
|
606
|
+
producer_version=producer_version,
|
|
607
|
+
created_at=created_at,
|
|
608
|
+
kind="invariant",
|
|
609
|
+
entry_type="requirement",
|
|
610
|
+
summary=text,
|
|
611
|
+
body=f"需求类型:invariant\n{text}",
|
|
612
|
+
keywords=_keywords("invariant", "requirement"),
|
|
613
|
+
source_refs=_plan_source_refs(change_key, f"plans/{change_key}-design.md"),
|
|
614
|
+
))
|
|
615
|
+
return out
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
def _tasks_from_plan(
|
|
619
|
+
plan_text: str,
|
|
620
|
+
*,
|
|
621
|
+
change_key: str,
|
|
622
|
+
archive_id: str,
|
|
623
|
+
producer_version: str,
|
|
624
|
+
created_at: str,
|
|
625
|
+
) -> list[dict[str, Any]]:
|
|
626
|
+
"""Parse ``## Tasks`` from plan.md into implementation candidates.
|
|
627
|
+
|
|
628
|
+
Task headings are ``### T1``; the objective is the non-empty text between
|
|
629
|
+
the heading and the first ``- `` metadata bullet.
|
|
630
|
+
"""
|
|
631
|
+
sections = _markdown_sections(plan_text)
|
|
632
|
+
lines = sections.get("Tasks", [])
|
|
633
|
+
out: list[dict[str, Any]] = []
|
|
634
|
+
index = 0
|
|
635
|
+
while index < len(lines):
|
|
636
|
+
stripped = lines[index].strip()
|
|
637
|
+
if not stripped.startswith("### "):
|
|
638
|
+
index += 1
|
|
639
|
+
continue
|
|
640
|
+
task_id = stripped[4:].strip()
|
|
641
|
+
index += 1
|
|
642
|
+
objective_parts: list[str] = []
|
|
643
|
+
while index < len(lines):
|
|
644
|
+
current = lines[index].strip()
|
|
645
|
+
if current.startswith("### ") or current.startswith("- "):
|
|
646
|
+
break
|
|
647
|
+
if current:
|
|
648
|
+
objective_parts.append(current)
|
|
649
|
+
index += 1
|
|
650
|
+
objective = " ".join(objective_parts).strip()
|
|
651
|
+
if not objective:
|
|
652
|
+
continue
|
|
653
|
+
body = f"任务:{task_id}\n{objective}"
|
|
654
|
+
out.append(_plan_candidate(
|
|
655
|
+
change_key=change_key,
|
|
656
|
+
archive_id=archive_id,
|
|
657
|
+
producer_version=producer_version,
|
|
658
|
+
created_at=created_at,
|
|
659
|
+
kind="task",
|
|
660
|
+
entry_type="implementation",
|
|
661
|
+
summary=objective,
|
|
662
|
+
body=body,
|
|
663
|
+
keywords=_keywords(task_id, "implementation"),
|
|
664
|
+
source_refs=_plan_source_refs(change_key, f"plans/{change_key}-plan.md"),
|
|
665
|
+
))
|
|
666
|
+
return out
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
def _scenarios_from_test_scenarios(
|
|
670
|
+
scenarios_text: str,
|
|
671
|
+
*,
|
|
672
|
+
change_key: str,
|
|
673
|
+
archive_id: str,
|
|
674
|
+
producer_version: str,
|
|
675
|
+
created_at: str,
|
|
676
|
+
) -> list[dict[str, Any]]:
|
|
677
|
+
"""Parse ``## <id>: <title>`` headings into test-evidence candidates."""
|
|
678
|
+
out: list[dict[str, Any]] = []
|
|
679
|
+
for line in scenarios_text.splitlines():
|
|
680
|
+
stripped = line.strip()
|
|
681
|
+
if not stripped.startswith("## ") or stripped.startswith("### "):
|
|
682
|
+
continue
|
|
683
|
+
heading = stripped[3:].strip()
|
|
684
|
+
if heading == "Coverage":
|
|
685
|
+
continue
|
|
686
|
+
if ":" not in heading:
|
|
687
|
+
continue
|
|
688
|
+
scenario_id, title = heading.split(":", 1)
|
|
689
|
+
title = title.strip()
|
|
690
|
+
if not title:
|
|
691
|
+
continue
|
|
692
|
+
out.append(_plan_candidate(
|
|
693
|
+
change_key=change_key,
|
|
694
|
+
archive_id=archive_id,
|
|
695
|
+
producer_version=producer_version,
|
|
696
|
+
created_at=created_at,
|
|
697
|
+
kind="scenario",
|
|
698
|
+
entry_type="test-evidence",
|
|
699
|
+
summary=title,
|
|
700
|
+
body=f"场景:{scenario_id.strip()}\n{title}",
|
|
701
|
+
keywords=_keywords(scenario_id.strip(), "test-evidence"),
|
|
702
|
+
source_refs=_plan_source_refs(
|
|
703
|
+
change_key, f"plans/{change_key}-test-scenarios.md"
|
|
704
|
+
),
|
|
705
|
+
))
|
|
706
|
+
return out
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
def build_plan_candidates(
|
|
710
|
+
archive_dir,
|
|
711
|
+
*,
|
|
712
|
+
change_key: str,
|
|
713
|
+
archive_id: str,
|
|
714
|
+
producer_version: str,
|
|
715
|
+
created_at: str,
|
|
716
|
+
) -> list[dict[str, Any]]:
|
|
717
|
+
"""Extract knowledge candidates from the archive's plans/*.md artifacts.
|
|
718
|
+
|
|
719
|
+
Complements ``build_knowledge_candidates`` (summary 三源)。没有评审的简单
|
|
720
|
+
变更仍然产出 plans/*.md;这些是经用户确认批准的结构化真相源,parse 回来
|
|
721
|
+
就是可沉淀的知识。缺文件/解析失败返回 [](软失败)。
|
|
722
|
+
"""
|
|
723
|
+
candidates: list[dict[str, Any]] = []
|
|
724
|
+
seen_ids: set[str] = set()
|
|
725
|
+
|
|
726
|
+
def collect(items: list[dict[str, Any]]) -> None:
|
|
727
|
+
for candidate in items:
|
|
728
|
+
if candidate["candidate_id"] in seen_ids:
|
|
729
|
+
continue
|
|
730
|
+
seen_ids.add(candidate["candidate_id"])
|
|
731
|
+
candidates.append(candidate)
|
|
732
|
+
|
|
733
|
+
design_path = archive_dir / "plans" / f"{change_key}-design.md"
|
|
734
|
+
if design_path.is_file():
|
|
735
|
+
try:
|
|
736
|
+
design_text = design_path.read_text(encoding="utf-8-sig")
|
|
737
|
+
except OSError:
|
|
738
|
+
design_text = ""
|
|
739
|
+
collect(_requirements_from_design(
|
|
740
|
+
design_text,
|
|
741
|
+
change_key=change_key,
|
|
742
|
+
archive_id=archive_id,
|
|
743
|
+
producer_version=producer_version,
|
|
744
|
+
created_at=created_at,
|
|
745
|
+
))
|
|
746
|
+
collect(_risks_from_design(
|
|
747
|
+
design_text,
|
|
748
|
+
change_key=change_key,
|
|
749
|
+
archive_id=archive_id,
|
|
750
|
+
producer_version=producer_version,
|
|
751
|
+
created_at=created_at,
|
|
752
|
+
))
|
|
753
|
+
collect(_invariants_from_design(
|
|
754
|
+
design_text,
|
|
755
|
+
change_key=change_key,
|
|
756
|
+
archive_id=archive_id,
|
|
757
|
+
producer_version=producer_version,
|
|
758
|
+
created_at=created_at,
|
|
759
|
+
))
|
|
760
|
+
|
|
761
|
+
plan_path = archive_dir / "plans" / f"{change_key}-plan.md"
|
|
762
|
+
if plan_path.is_file():
|
|
763
|
+
try:
|
|
764
|
+
plan_text = plan_path.read_text(encoding="utf-8-sig")
|
|
765
|
+
except OSError:
|
|
766
|
+
plan_text = ""
|
|
767
|
+
collect(_tasks_from_plan(
|
|
768
|
+
plan_text,
|
|
769
|
+
change_key=change_key,
|
|
770
|
+
archive_id=archive_id,
|
|
771
|
+
producer_version=producer_version,
|
|
772
|
+
created_at=created_at,
|
|
773
|
+
))
|
|
774
|
+
|
|
775
|
+
scenarios_path = archive_dir / "plans" / f"{change_key}-test-scenarios.md"
|
|
776
|
+
if scenarios_path.is_file():
|
|
777
|
+
try:
|
|
778
|
+
scenarios_text = scenarios_path.read_text(encoding="utf-8-sig")
|
|
779
|
+
except OSError:
|
|
780
|
+
scenarios_text = ""
|
|
781
|
+
collect(_scenarios_from_test_scenarios(
|
|
782
|
+
scenarios_text,
|
|
783
|
+
change_key=change_key,
|
|
784
|
+
archive_id=archive_id,
|
|
785
|
+
producer_version=producer_version,
|
|
786
|
+
created_at=created_at,
|
|
787
|
+
))
|
|
788
|
+
|
|
255
789
|
return candidates
|
|
256
790
|
|
|
257
791
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Harness Skills
|
|
2
|
+
|
|
3
|
+
Harness Skills 是一组围绕本地变更治理的 agent 工作流。它把外部方法论吸收为原生协议,同时保持 `.harness/changes/<change-name>/` 作为变更过程的唯一真相源。
|
|
4
|
+
|
|
5
|
+
## Language
|
|
6
|
+
|
|
7
|
+
**原生协议**:
|
|
8
|
+
Harness skill 内部直接执行的流程约束,作为正式行为契约。原生协议可以吸收外部方法论,但不依赖外部 skill 是否安装。
|
|
9
|
+
_Avoid_: Adapter Mode, 外部 skill 调用
|
|
10
|
+
|
|
11
|
+
**外部方法论来源**:
|
|
12
|
+
为 harness 规则提供启发的外部 skill 或流程,例如 brainstorming、grill-me、writing-plans、test-driven-development、receiving-code-review。它们是设计来源,不是 harness 的运行时依赖。
|
|
13
|
+
_Avoid_: 外部依赖, 必需插件
|
|
14
|
+
|
|
15
|
+
**人工参考**:
|
|
16
|
+
不进入正式流程状态机、只供人或后续规则维护者对标的方法、草稿或外部技能。人工参考缺失不产生降级项;若被采用,应先转写为 harness 原生协议或正式产物。
|
|
17
|
+
_Avoid_: 运行时增强, 降级分支, 硬依赖
|
|
18
|
+
|
|
19
|
+
**变更簇**:
|
|
20
|
+
围绕同一业务行为或同一验证目标的一组任务。变更簇是 `/harness-run` 执行 RED→GREEN→REFACTOR 的基本单位。
|
|
21
|
+
_Avoid_: 小任务, 单步任务
|
|
22
|
+
|
|
23
|
+
**自适应执行参考**:
|
|
24
|
+
`implementation-detail.md` 的定位。它按变更复杂度提供足够执行上下文,简单变更保持简洁,高风险变更写清顺序、接口、数据、风险和测试策略。
|
|
25
|
+
_Avoid_: 超细步骤文档, 可选详细计划
|
|
26
|
+
|
|
27
|
+
**Fixback**:
|
|
28
|
+
由 review 阶段把 RED/YELLOW 问题转成的结构化修复反馈。Fixback 指向问题位置、推荐修复和验证方式,但默认不自动阻塞 submit。
|
|
29
|
+
_Avoid_: 修复任务清单, blocking review
|
|
30
|
+
|
|
31
|
+
**事件唯一源**:
|
|
32
|
+
`events.ndjson` 是变更执行过程的唯一实时记录位置,由 `harness_events.py append` 写入。`execution-log.md` 是它的自动渲染产物,禁止手工编辑。
|
|
33
|
+
_Avoid_: 日志双写, 手写执行日志
|
|
34
|
+
|
|
35
|
+
**归档终结(finalize)**:
|
|
36
|
+
`harness_archive.py finalize` 在单进程内完成 manifest、移动、collect、渲染、校验、比对、删除原目录的完整归档动作。取代旧的 collect/enrich/validate 三步编排;enrich 不再是有效概念。
|
|
37
|
+
_Avoid_: enrich, 多步归档编排
|
|
38
|
+
|
|
39
|
+
**知识裁决(judge)**:
|
|
40
|
+
归档收尾时对知识条目的处置流程:脚本规则先消化机械部分(去重、时间序 supersede、stale 重验),模型批量裁决剩余的真语义冲突与 promote,写入可回滚的 decision log。人工退出常规循环。
|
|
41
|
+
_Avoid_: 人工 promote 积压, candidate 待办
|
|
42
|
+
|
|
43
|
+
**构建档案(build-profile)**:
|
|
44
|
+
`.harness/config/build-profile.json`,项目级持久化的机读构建事实:可用命令模板、工具绝对路径、已知预存错误、服务启动模板。preflight 只做秒级校验,新坑由脚本回写。项目专属硬编码归此文件,不进 skill 文本。
|
|
45
|
+
_Avoid_: 每次重新探测, skill 内硬编码项目参数
|
|
46
|
+
|
|
47
|
+
**验证指纹(inputsHash)**:
|
|
48
|
+
一项验证(compile/install/unitTest/apiTest)所依赖源文件集合的内容哈希。指纹一致且证据完整才允许 🔁REUSED;无法证明即保守重跑。
|
|
49
|
+
_Avoid_: 仅凭 diffHash 复用, 无证据跳过
|
|
50
|
+
|
|
51
|
+
**验证图(verification graph)**:
|
|
52
|
+
`evidence/verification-graph.json` 按 canonical identity 持久化验证节点;`can-reuse` 返回 `invalidationCode`(如 `INPUT_CHANGED`);profile `mergeVerification.requiredOnMerge` 进入 integration verify。详见 ledger / integration 脚本。
|
|
53
|
+
_Avoid_: 冻结后无因重跑全量
|
|
54
|
+
|
|
55
|
+
**Migration head 单源**:
|
|
56
|
+
消费项目用 `.harness/config/migration-head.json` 声明 canonical head 与联动 sources;`harness_migration_head.py check` 做静态一致性门禁。
|
|
57
|
+
_Avoid_: config/CI/manifest 多处手写 head
|
|
58
|
+
|
|
59
|
+
**事件批处理**:
|
|
60
|
+
同阶段多事件用 `harness_events.py batch-append`(单锁多行);`phase.end` 仍走单次 append。
|
|
61
|
+
_Avoid_: 机械事件逐条起进程
|
|
62
|
+
|
|
63
|
+
**能力级模型路由**:
|
|
64
|
+
任务用 `economy` / `balanced` / `frontier` 表述;禁止在通用 harness 规则硬编码供应商模型名。详见 `protocols/model-routing-protocol.md`。
|
|
65
|
+
_Avoid_: skill 内写死 claude-/gpt- 模型 id
|
|
66
|
+
|
|
67
|
+
**Overlay 所有权**:
|
|
68
|
+
Bundle 安装目标由安装器管理;项目自有配置放 `.harness/project-overlay/`(或 project.yaml 侧)。`--force-managed` 必须配合 `--yes`/`--confirmed`,冲突 fail closed。
|
|
69
|
+
_Avoid_: 静默 force-managed
|
|
70
|
+
|
|
71
|
+
**服务会话**:
|
|
72
|
+
`runtime/service-session.json` 记录的 AI 启动服务生命周期。指纹匹配静默复用、不匹配自动重启、归档收尾统一停止;只有用户自启服务占端口才询问。
|
|
73
|
+
_Avoid_: 每轮测试后必杀服务
|
|
74
|
+
|
|
75
|
+
**交互白名单**:
|
|
76
|
+
每个 skill 显式声明的允许 `blocking user confirmation` 场景清单。白名单外一律取默认值并记 decision 事件。
|
|
77
|
+
_Avoid_: 逐决策点询问
|
|
78
|
+
|
|
79
|
+
**阻断式用户确认(blocking user confirmation)**:
|
|
80
|
+
宿主无关的审批原语。canonical skill 使用此术语表达"展示完整审批包并等待明确答复"的语义,不绑定具体宿主工具。adapter 按下表映射到宿主具体工具:
|
|
81
|
+
|
|
82
|
+
| Adapter | 工具 |
|
|
83
|
+
|---------|------|
|
|
84
|
+
| claude-code | AskUserQuestion |
|
|
85
|
+
| codebuddy | AskUserQuestion |
|
|
86
|
+
| codex | request_user_input 或普通对话 |
|
|
87
|
+
| cursor | 普通对话 |
|
|
88
|
+
|
|
89
|
+
finalizer 只校验 approval receipt/decision 的顺序和内容,不校验交互工具品牌。
|
|
90
|
+
_Avoid_: 硬编码宿主工具名, 跨宿主不可移植
|
|
91
|
+
|
|
92
|
+
**部署合成**:
|
|
93
|
+
`harness_deploy.py build` 把通用核心 + shared 片段 + overlay 合成为自包含 SKILL.md 后部署。Vault 源头 DRY,运行时单文件。
|
|
94
|
+
_Avoid_: 运行时跨文件拼规则, fork 维护
|
|
95
|
+
|
|
96
|
+
**Java overlay**:
|
|
97
|
+
`overlays/java/` 中只含"任何 Java 项目通用"的差异段落与独有 skill(apidoc/package)。项目专属值写目标项目的 build-profile。
|
|
98
|
+
_Avoid_: Java fork, UDP 硬编码进 overlay
|