@hunter-harness/workflow-harness 0.2.42 → 0.2.44
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/build-profile-v3.schema.json +156 -1
- package/harness/bundles/general/claude-code/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/general/claude-code/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/general/claude-code/contracts/run-session.schema.json +142 -0
- package/harness/bundles/general/claude-code/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/general/claude-code/contracts/service-session.schema.json +147 -0
- package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-archive/reference.md +1 -0
- package/harness/bundles/general/claude-code/harness-archive/templates/render-summary.mjs +8 -0
- package/harness/bundles/general/claude-code/harness-archive/templates/summary-data-template.json +28 -0
- package/harness/bundles/general/claude-code/harness-codebase-map/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-review/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-run/reference.md +6 -1
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-submit/checklist.md +12 -0
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +8 -2
- package/harness/bundles/general/claude-code/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/general/claude-code/protocols/state-layout-protocol.md +24 -1
- package/harness/bundles/general/claude-code/protocols/verification-graph-protocol.md +6 -0
- package/harness/bundles/general/claude-code/scripts/harness_archive.py +271 -22
- package/harness/bundles/general/claude-code/scripts/harness_change.py +137 -2
- package/harness/bundles/general/claude-code/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/general/claude-code/scripts/harness_environment.py +760 -46
- package/harness/bundles/general/claude-code/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/general/claude-code/scripts/harness_fixback.py +742 -0
- package/harness/bundles/general/claude-code/scripts/harness_integration.py +289 -52
- package/harness/bundles/general/claude-code/scripts/harness_ledger.py +5 -0
- package/harness/bundles/general/claude-code/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/general/claude-code/scripts/harness_process.py +1065 -0
- package/harness/bundles/general/claude-code/scripts/harness_profile.py +278 -4
- package/harness/bundles/general/claude-code/scripts/harness_runtime.py +1576 -3
- package/harness/bundles/general/claude-code/scripts/harness_service.py +1528 -177
- package/harness/bundles/general/claude-code/scripts/harness_test_runner.py +224 -146
- package/harness/bundles/general/claude-code/scripts/harness_verification.py +487 -8
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/contracts/build-profile-v3.schema.json +156 -1
- package/harness/bundles/general/codebuddy/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/general/codebuddy/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/general/codebuddy/contracts/run-session.schema.json +142 -0
- package/harness/bundles/general/codebuddy/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/general/codebuddy/contracts/service-session.schema.json +147 -0
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/reference.md +1 -0
- package/harness/bundles/general/codebuddy/harness-archive/templates/render-summary.mjs +8 -0
- package/harness/bundles/general/codebuddy/harness-archive/templates/summary-data-template.json +28 -0
- package/harness/bundles/general/codebuddy/harness-codebase-map/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-review/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-run/reference.md +6 -1
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-submit/checklist.md +12 -0
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +8 -2
- package/harness/bundles/general/codebuddy/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/general/codebuddy/protocols/state-layout-protocol.md +24 -1
- package/harness/bundles/general/codebuddy/protocols/verification-graph-protocol.md +6 -0
- package/harness/bundles/general/codebuddy/scripts/harness_archive.py +271 -22
- package/harness/bundles/general/codebuddy/scripts/harness_change.py +137 -2
- package/harness/bundles/general/codebuddy/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/general/codebuddy/scripts/harness_environment.py +760 -46
- package/harness/bundles/general/codebuddy/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/general/codebuddy/scripts/harness_fixback.py +742 -0
- package/harness/bundles/general/codebuddy/scripts/harness_integration.py +289 -52
- package/harness/bundles/general/codebuddy/scripts/harness_ledger.py +5 -0
- package/harness/bundles/general/codebuddy/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/general/codebuddy/scripts/harness_process.py +1065 -0
- package/harness/bundles/general/codebuddy/scripts/harness_profile.py +278 -4
- package/harness/bundles/general/codebuddy/scripts/harness_runtime.py +1576 -3
- package/harness/bundles/general/codebuddy/scripts/harness_service.py +1528 -177
- package/harness/bundles/general/codebuddy/scripts/harness_test_runner.py +224 -146
- package/harness/bundles/general/codebuddy/scripts/harness_verification.py +487 -8
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/contracts/build-profile-v3.schema.json +156 -1
- package/harness/bundles/general/codex/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/general/codex/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/general/codex/contracts/run-session.schema.json +142 -0
- package/harness/bundles/general/codex/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/general/codex/contracts/service-session.schema.json +147 -0
- package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-archive/reference.md +1 -0
- package/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +8 -0
- package/harness/bundles/general/codex/harness-archive/templates/summary-data-template.json +28 -0
- package/harness/bundles/general/codex/harness-codebase-map/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-review/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-run/reference.md +6 -1
- package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-submit/checklist.md +12 -0
- package/harness/bundles/general/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-test/SKILL.md +8 -2
- package/harness/bundles/general/codex/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/general/codex/protocols/state-layout-protocol.md +24 -1
- package/harness/bundles/general/codex/protocols/verification-graph-protocol.md +6 -0
- package/harness/bundles/general/codex/scripts/harness_archive.py +271 -22
- package/harness/bundles/general/codex/scripts/harness_change.py +137 -2
- package/harness/bundles/general/codex/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/general/codex/scripts/harness_environment.py +760 -46
- package/harness/bundles/general/codex/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/general/codex/scripts/harness_fixback.py +742 -0
- package/harness/bundles/general/codex/scripts/harness_integration.py +289 -52
- package/harness/bundles/general/codex/scripts/harness_ledger.py +5 -0
- package/harness/bundles/general/codex/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/general/codex/scripts/harness_process.py +1065 -0
- package/harness/bundles/general/codex/scripts/harness_profile.py +278 -4
- package/harness/bundles/general/codex/scripts/harness_runtime.py +1576 -3
- package/harness/bundles/general/codex/scripts/harness_service.py +1528 -177
- package/harness/bundles/general/codex/scripts/harness_test_runner.py +224 -146
- package/harness/bundles/general/codex/scripts/harness_verification.py +487 -8
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/contracts/build-profile-v3.schema.json +156 -1
- package/harness/bundles/general/cursor/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/general/cursor/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/general/cursor/contracts/run-session.schema.json +142 -0
- package/harness/bundles/general/cursor/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/general/cursor/contracts/service-session.schema.json +147 -0
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-archive/reference.md +1 -0
- package/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +8 -0
- package/harness/bundles/general/cursor/harness-archive/templates/summary-data-template.json +28 -0
- package/harness/bundles/general/cursor/harness-codebase-map/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-review/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-run/reference.md +6 -1
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-submit/checklist.md +12 -0
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-test/SKILL.md +8 -2
- package/harness/bundles/general/cursor/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/general/cursor/protocols/state-layout-protocol.md +24 -1
- package/harness/bundles/general/cursor/protocols/verification-graph-protocol.md +6 -0
- package/harness/bundles/general/cursor/scripts/harness_archive.py +271 -22
- package/harness/bundles/general/cursor/scripts/harness_change.py +137 -2
- package/harness/bundles/general/cursor/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/general/cursor/scripts/harness_environment.py +760 -46
- package/harness/bundles/general/cursor/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/general/cursor/scripts/harness_fixback.py +742 -0
- package/harness/bundles/general/cursor/scripts/harness_integration.py +289 -52
- package/harness/bundles/general/cursor/scripts/harness_ledger.py +5 -0
- package/harness/bundles/general/cursor/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/general/cursor/scripts/harness_process.py +1065 -0
- package/harness/bundles/general/cursor/scripts/harness_profile.py +278 -4
- package/harness/bundles/general/cursor/scripts/harness_runtime.py +1576 -3
- package/harness/bundles/general/cursor/scripts/harness_service.py +1528 -177
- package/harness/bundles/general/cursor/scripts/harness_test_runner.py +224 -146
- package/harness/bundles/general/cursor/scripts/harness_verification.py +487 -8
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/contracts/build-profile-v3.schema.json +156 -1
- package/harness/bundles/java/claude-code/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/java/claude-code/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/java/claude-code/contracts/run-session.schema.json +142 -0
- package/harness/bundles/java/claude-code/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/java/claude-code/contracts/service-session.schema.json +147 -0
- 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 +1 -0
- package/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +8 -0
- package/harness/bundles/java/claude-code/harness-archive/templates/summary-data-template.json +28 -0
- package/harness/bundles/java/claude-code/harness-codebase-map/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-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-submit/checklist.md +12 -0
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +8 -2
- package/harness/bundles/java/claude-code/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +24 -1
- package/harness/bundles/java/claude-code/protocols/verification-graph-protocol.md +6 -0
- package/harness/bundles/java/claude-code/scripts/harness_archive.py +271 -22
- package/harness/bundles/java/claude-code/scripts/harness_change.py +137 -2
- package/harness/bundles/java/claude-code/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/java/claude-code/scripts/harness_environment.py +760 -46
- package/harness/bundles/java/claude-code/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/java/claude-code/scripts/harness_fixback.py +742 -0
- package/harness/bundles/java/claude-code/scripts/harness_integration.py +289 -52
- package/harness/bundles/java/claude-code/scripts/harness_ledger.py +5 -0
- package/harness/bundles/java/claude-code/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/java/claude-code/scripts/harness_process.py +1065 -0
- package/harness/bundles/java/claude-code/scripts/harness_profile.py +278 -4
- package/harness/bundles/java/claude-code/scripts/harness_runtime.py +1576 -3
- package/harness/bundles/java/claude-code/scripts/harness_service.py +1528 -177
- package/harness/bundles/java/claude-code/scripts/harness_test_runner.py +224 -146
- package/harness/bundles/java/claude-code/scripts/harness_verification.py +487 -8
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/contracts/build-profile-v3.schema.json +156 -1
- package/harness/bundles/java/codebuddy/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/java/codebuddy/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/java/codebuddy/contracts/run-session.schema.json +142 -0
- package/harness/bundles/java/codebuddy/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/java/codebuddy/contracts/service-session.schema.json +147 -0
- 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 +1 -0
- package/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +8 -0
- package/harness/bundles/java/codebuddy/harness-archive/templates/summary-data-template.json +28 -0
- package/harness/bundles/java/codebuddy/harness-codebase-map/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-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-submit/checklist.md +12 -0
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +8 -2
- package/harness/bundles/java/codebuddy/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +24 -1
- package/harness/bundles/java/codebuddy/protocols/verification-graph-protocol.md +6 -0
- package/harness/bundles/java/codebuddy/scripts/harness_archive.py +271 -22
- package/harness/bundles/java/codebuddy/scripts/harness_change.py +137 -2
- package/harness/bundles/java/codebuddy/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/java/codebuddy/scripts/harness_environment.py +760 -46
- package/harness/bundles/java/codebuddy/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/java/codebuddy/scripts/harness_fixback.py +742 -0
- package/harness/bundles/java/codebuddy/scripts/harness_integration.py +289 -52
- package/harness/bundles/java/codebuddy/scripts/harness_ledger.py +5 -0
- package/harness/bundles/java/codebuddy/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/java/codebuddy/scripts/harness_process.py +1065 -0
- package/harness/bundles/java/codebuddy/scripts/harness_profile.py +278 -4
- package/harness/bundles/java/codebuddy/scripts/harness_runtime.py +1576 -3
- package/harness/bundles/java/codebuddy/scripts/harness_service.py +1528 -177
- package/harness/bundles/java/codebuddy/scripts/harness_test_runner.py +224 -146
- package/harness/bundles/java/codebuddy/scripts/harness_verification.py +487 -8
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/contracts/build-profile-v3.schema.json +156 -1
- package/harness/bundles/java/codex/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/java/codex/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/java/codex/contracts/run-session.schema.json +142 -0
- package/harness/bundles/java/codex/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/java/codex/contracts/service-session.schema.json +147 -0
- 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 +1 -0
- package/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +8 -0
- package/harness/bundles/java/codex/harness-archive/templates/summary-data-template.json +28 -0
- package/harness/bundles/java/codex/harness-codebase-map/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-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-submit/checklist.md +12 -0
- package/harness/bundles/java/codex/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-test/SKILL.md +8 -2
- package/harness/bundles/java/codex/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/java/codex/protocols/state-layout-protocol.md +24 -1
- package/harness/bundles/java/codex/protocols/verification-graph-protocol.md +6 -0
- package/harness/bundles/java/codex/scripts/harness_archive.py +271 -22
- package/harness/bundles/java/codex/scripts/harness_change.py +137 -2
- package/harness/bundles/java/codex/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/java/codex/scripts/harness_environment.py +760 -46
- package/harness/bundles/java/codex/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/java/codex/scripts/harness_fixback.py +742 -0
- package/harness/bundles/java/codex/scripts/harness_integration.py +289 -52
- package/harness/bundles/java/codex/scripts/harness_ledger.py +5 -0
- package/harness/bundles/java/codex/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/java/codex/scripts/harness_process.py +1065 -0
- package/harness/bundles/java/codex/scripts/harness_profile.py +278 -4
- package/harness/bundles/java/codex/scripts/harness_runtime.py +1576 -3
- package/harness/bundles/java/codex/scripts/harness_service.py +1528 -177
- package/harness/bundles/java/codex/scripts/harness_test_runner.py +224 -146
- package/harness/bundles/java/codex/scripts/harness_verification.py +487 -8
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/contracts/build-profile-v3.schema.json +156 -1
- package/harness/bundles/java/cursor/contracts/fixtures/managed-execution.json +341 -0
- package/harness/bundles/java/cursor/contracts/process-identity.schema.json +132 -0
- package/harness/bundles/java/cursor/contracts/run-session.schema.json +142 -0
- package/harness/bundles/java/cursor/contracts/service-retirement-receipt.schema.json +85 -0
- package/harness/bundles/java/cursor/contracts/service-session.schema.json +147 -0
- 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 +1 -0
- package/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +8 -0
- package/harness/bundles/java/cursor/harness-archive/templates/summary-data-template.json +28 -0
- package/harness/bundles/java/cursor/harness-codebase-map/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-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-submit/checklist.md +12 -0
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-test/SKILL.md +8 -2
- package/harness/bundles/java/cursor/protocols/execution-session-protocol.md +52 -0
- package/harness/bundles/java/cursor/protocols/state-layout-protocol.md +24 -1
- package/harness/bundles/java/cursor/protocols/verification-graph-protocol.md +6 -0
- package/harness/bundles/java/cursor/scripts/harness_archive.py +271 -22
- package/harness/bundles/java/cursor/scripts/harness_change.py +137 -2
- package/harness/bundles/java/cursor/scripts/harness_efficiency.py +443 -0
- package/harness/bundles/java/cursor/scripts/harness_environment.py +760 -46
- package/harness/bundles/java/cursor/scripts/harness_execution_contracts.py +596 -0
- package/harness/bundles/java/cursor/scripts/harness_fixback.py +742 -0
- package/harness/bundles/java/cursor/scripts/harness_integration.py +289 -52
- package/harness/bundles/java/cursor/scripts/harness_ledger.py +5 -0
- package/harness/bundles/java/cursor/scripts/harness_orchestration.py +344 -0
- package/harness/bundles/java/cursor/scripts/harness_process.py +1065 -0
- package/harness/bundles/java/cursor/scripts/harness_profile.py +278 -4
- package/harness/bundles/java/cursor/scripts/harness_runtime.py +1576 -3
- package/harness/bundles/java/cursor/scripts/harness_service.py +1528 -177
- package/harness/bundles/java/cursor/scripts/harness_test_runner.py +224 -146
- package/harness/bundles/java/cursor/scripts/harness_verification.py +487 -8
- package/harness/manifests/general/claude-code.json +76 -31
- package/harness/manifests/general/codebuddy.json +76 -31
- package/harness/manifests/general/codex.json +76 -31
- package/harness/manifests/general/cursor.json +76 -31
- package/harness/manifests/java/claude-code.json +77 -32
- package/harness/manifests/java/codebuddy.json +77 -32
- package/harness/manifests/java/codex.json +77 -32
- package/harness/manifests/java/cursor.json +77 -32
- package/hunter-workflow-family.json +6 -4
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 长时命令、验证调度、环境复用与 fixback 的可恢复执行协议。
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Execution Session Protocol
|
|
6
|
+
|
|
7
|
+
## 受管运行会话
|
|
8
|
+
|
|
9
|
+
可能超过交互窗口的命令必须通过 `harness_runtime.py run-start` 创建受管会话,而不是依赖调用方进程持续在线。会话状态位于:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
runtime/run-sessions/<session-id>/
|
|
13
|
+
├── session.json
|
|
14
|
+
├── stdout.log
|
|
15
|
+
├── stderr.log
|
|
16
|
+
└── worker.log
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`session.json` 只持久化脱敏身份:命令哈希、环境哈希、产品身份、验证目标、阶段、资源锁、进程身份、心跳、进度、超时和原因码。原始环境变量和敏感 argv 不得写入回执。
|
|
20
|
+
|
|
21
|
+
- `run-status` 可由新进程重连;心跳丢失超过 grace period 才标记 `INCOMPLETE`。
|
|
22
|
+
- `run-log --cursor` 按字节游标增量读取 UTF-8 日志,返回下一游标。
|
|
23
|
+
- `run-cancel` 只终止身份完全匹配的进程树;身份不确定时 fail closed。
|
|
24
|
+
- launcher 尚未启动子进程时失败,状态为 `INCOMPLETE/LAUNCHER_FAILED`;子进程非零退出为 `FAIL/CHILD_EXIT_NONZERO`;超时为 `CANCELLED/TIMEOUT`。
|
|
25
|
+
- `resourceLocks` 通过 `runtime/resource-locks/<lock-hash>.json` 原子独占;冲突会在启动测试进程前返回 `INCOMPLETE/RESOURCE_LOCK_BUSY`,终态写入前必须释放持有的锁。
|
|
26
|
+
- Windows 使用 shell-free argv 和 kill-on-close Job Object;Job Object 绑定失败时必须终止已验证的子进程并返回 `PROCESS_TREE_ISOLATION_UNAVAILABLE`,不得降级为无隔离运行。
|
|
27
|
+
|
|
28
|
+
## 验证调度
|
|
29
|
+
|
|
30
|
+
`harness_verification.py plan` 对验证 DAG 做拓扑调度。每个目标声明 `dependsOn`、`resourceLocks`、identity 与复用策略。
|
|
31
|
+
|
|
32
|
+
- 只有资源锁不相交的 ready 目标可进入同一 wave。
|
|
33
|
+
- 未声明资源锁且预计大于等于 60 秒的目标自动使用 `harness:unclassified-heavy`,因此默认串行。
|
|
34
|
+
- 冻结后的产品 identity 发生变化时返回 `FROZEN_IDENTITY_DRIFT`,禁止继续执行或复用。
|
|
35
|
+
- 复用和跳过必须记录 `decision`、`reasonCode` 与人类可读 `explanation`;无证据不得返回 `REUSE`。
|
|
36
|
+
|
|
37
|
+
## 环境会话
|
|
38
|
+
|
|
39
|
+
环境租约支持两种模式:
|
|
40
|
+
|
|
41
|
+
- `change-session`:同一 change、stack、内容指纹和通过的 canary 可复用。
|
|
42
|
+
- `ephemeral`:每次 acquire 都创建新 session;替换既有 session 前必须提供匹配 stack/environment identity 的 provider reset 回执。
|
|
43
|
+
|
|
44
|
+
租约获取通过注册锁原子串行化,跨 change 的 writable volume 永不共享。`change-session` 只有在内容指纹非空、environment hash、owner identity、expiry、mode、volume 和 canary 全部匹配时才可复用。内容指纹漂移标记 `STALE_CONTENT`;过期租约不可写。prepare/reuse 写入事实回执;reset/cleanup 只有在 provider operation evidence 为 `OK` 时才可如此命名。单纯释放租约只能记录 `release`,不得声称已清理外部环境。回执写入 change 的 `runtime/environment-receipts/`,文件名使用 stack hash,且不包含凭据明文。
|
|
45
|
+
|
|
46
|
+
## Fixback 批次
|
|
47
|
+
|
|
48
|
+
Review/Test 回灌通过 `harness_fixback.py` 形成批次。一个批次可包含多条相关问题,但每条问题必须保留可读取的 JSON RED/GREEN 证据。证据必须位于项目或 change state 内,包含 evidence id、状态和产品 identity,并在批次中固定 SHA-256;RED 必须为 `FAIL`,GREEN 必须为 `PASS/OK`。affected verification 与 review 回执必须绑定最终产品 identity,其 `passedGates` 合集覆盖风险扩展后的全部门禁。`freeze-readiness` 会重新校验证据摘要;开放问题、证据漂移或缺门禁均阻止 code freeze。
|
|
49
|
+
|
|
50
|
+
## 效率摘要
|
|
51
|
+
|
|
52
|
+
`harness_efficiency.py summary` 从运行会话、环境回执和失效回执生成事实型指标:墙钟区间并集、累计活动/资源等待、execution/launcher/verification 尝试、失败分类、环境 prepare/reuse/reset/cleanup、重复且没有新 result digest 的命令和人工 wrapper 数。reset/cleanup 只统计带有效 provider evidence 的回执。归档摘要自动包含该结构;指标不得归责个人,也不得在历史样本不足时虚构 ETA。
|
|
@@ -60,7 +60,14 @@ description: harness .harness 状态目录分层协议。用于减少根目录
|
|
|
60
60
|
├── sqls/
|
|
61
61
|
├── scripts/
|
|
62
62
|
├── runtime/
|
|
63
|
-
│
|
|
63
|
+
│ ├── service-session.json
|
|
64
|
+
│ ├── run-sessions/<session-id>/
|
|
65
|
+
│ │ ├── session.json
|
|
66
|
+
│ │ ├── stdout.log
|
|
67
|
+
│ │ └── stderr.log
|
|
68
|
+
│ ├── environment-receipts/
|
|
69
|
+
│ ├── invalidations/
|
|
70
|
+
│ └── fixback/batches/
|
|
64
71
|
└── backups/
|
|
65
72
|
└── uncommitted-tests/
|
|
66
73
|
```
|
|
@@ -73,6 +80,10 @@ description: harness .harness 状态目录分层协议。用于减少根目录
|
|
|
73
80
|
|
|
74
81
|
`build-profile.json` 的 `serviceStart.inputFiles`(glob 列表,相对 project 展开)是 `moduleInputsHash` 的来源。`harness_service.py ensure` 取 CLI `--files` ∪ `serviceStart.inputFiles` 计算依赖闭包;**空输入被拒绝**(exit 非 0),**不得生成可复用的空指纹**。通用项目 detect 无法猜 module 源,`inputFiles` 默认空数组,须人工配置。
|
|
75
82
|
|
|
83
|
+
过期的 service session 只有在进程身份明确不匹配时才允许由 `retire-stale` 移入
|
|
84
|
+
`runtime/retired-service-sessions/`;该动作保留原始回执且不终止进程。受管命令、
|
|
85
|
+
环境会话和 fixback 的完整合同见 `execution-session-protocol.md`。
|
|
86
|
+
|
|
76
87
|
## knowledge maintenance-outbox(§8)
|
|
77
88
|
|
|
78
89
|
归档 close 不再同步执行知识维护;它写一个 pending outbox 项即返回:
|
|
@@ -179,3 +190,15 @@ Harness skill 读取的项目级配置(不提交 git)。缺失时使用下
|
|
|
179
190
|
| `knowledge.manualReview` | boolean | `false` | `true` 时 knowledge-ingest promote 等高价值操作需人工确认;`false` 时按 skill 默认策略 |
|
|
180
191
|
|
|
181
192
|
读取顺序:`.harness/config/harness.json` → 缺失则默认值。plan 阶段 5 设计审批包须读取 `defaultWorktree` 作为 worktree 选项的推荐值。
|
|
193
|
+
|
|
194
|
+
## 可恢复文件事务
|
|
195
|
+
|
|
196
|
+
schema v3 事务在本地 `transactions/<transaction-id>/` 保存 journal、before snapshot、staged payload、after manifest 和小型 status 投影。journal 固定 project identity、执行器版本、目标 Bundle identity、ownership manifest hash、plan hash 与 snapshot digest。
|
|
197
|
+
|
|
198
|
+
未完成事务同时镜像到用户级恢复根:
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
${HUNTER_HARNESS_RECOVERY_ROOT:-~/.hunter-harness/recovery}/<project-path-hash>/transactions/<transaction-id>/
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
因此项目内 `.harness` 局部丢失后,`status` 仍可只读发现恢复项。`resume` 仅在 plan/snapshot/staged digest 与已完成操作的当前文件状态全部匹配时继续 pending operations;任一不匹配均 fail closed。`rollback` 在写回 before snapshot 前重新校验 snapshot digest。事务提交或回滚成功后删除用户级镜像;本地 committed 事务仍按保留策略提供显式回滚。
|
|
@@ -11,6 +11,9 @@ Build Profile v3 用 `verificationGraph` 取代账本内的固定验证目标清
|
|
|
11
11
|
- `requiredCoverage`:`incremental/module-am/module`;
|
|
12
12
|
- `candidate`:是否为发布候选门禁;
|
|
13
13
|
- `requiredCapabilities`:执行环境必须具备的能力。
|
|
14
|
+
- `resourceLocks`:目标独占或共享的数据库、端口、浏览器、容器等资源身份;
|
|
15
|
+
- `estimatedDurationSeconds`:供默认串行策略和进度显示使用,不作为虚构 ETA 的依据;
|
|
16
|
+
- `reusePolicy`:允许复用时必须匹配的产品、环境、命令与覆盖身份。
|
|
14
17
|
|
|
15
18
|
`candidateTarget` 必须引用已声明目标。未知目标、未知依赖、循环依赖、命令缺失都 fail closed。
|
|
16
19
|
|
|
@@ -22,5 +25,8 @@ Build Profile v3 用 `verificationGraph` 取代账本内的固定验证目标清
|
|
|
22
25
|
4. 未进入闭包的目标是 `omitted`,与“执行失败”或“因能力阻断”分开报告。
|
|
23
26
|
5. 账本记录目标定义的规范化 identity;依赖、覆盖度或能力声明变化后,旧证据必须失效。
|
|
24
27
|
6. 候选目标即使自身命令可运行,也必须等待所有依赖和能力满足。
|
|
28
|
+
7. ready 目标按 `resourceLocks` 分 wave;锁相交的目标不得并行。预计 ≥60 秒且未声明锁的目标默认归入 `harness:unclassified-heavy` 串行队列。
|
|
29
|
+
8. code freeze 后产品 identity 漂移必须返回 `FROZEN_IDENTITY_DRIFT`;禁止在旧候选上补跑后声称覆盖新候选。
|
|
30
|
+
9. 每个 `RUN / REUSE / SKIP / BLOCKED` 决策都必须带稳定 `reasonCode` 和解释;`REUSE` 还必须绑定现有证据 identity。
|
|
25
31
|
|
|
26
32
|
JSON 合同见 `contracts/build-profile-v3.schema.json`;通用选择器为 `@hunter-harness/core` 的 `selectVerificationTargets`。
|
|
@@ -70,12 +70,14 @@ if str(SCRIPTS_DIR) not in sys.path:
|
|
|
70
70
|
sys.path.insert(0, str(SCRIPTS_DIR))
|
|
71
71
|
|
|
72
72
|
import harness_events as he # noqa: E402
|
|
73
|
+
import harness_efficiency as heff # noqa: E402
|
|
73
74
|
import harness_gate as hgate # noqa: E402
|
|
74
75
|
import harness_ledger as hl # noqa: E402
|
|
75
76
|
import harness_paths as hp # noqa: E402
|
|
76
77
|
import harness_phase as hphase # noqa: E402
|
|
77
78
|
import harness_report_model as hrm # noqa: E402
|
|
78
79
|
import harness_review as hr # noqa: E402
|
|
80
|
+
import harness_runtime as hruntime # noqa: E402
|
|
79
81
|
|
|
80
82
|
|
|
81
83
|
# ---------------------------------------------------------------------------
|
|
@@ -1956,6 +1958,131 @@ def check_archive_exact_byte_policy(project_root: Path) -> dict[str, Any]:
|
|
|
1956
1958
|
}
|
|
1957
1959
|
|
|
1958
1960
|
|
|
1961
|
+
def validate_sensitive_evidence_publication_gate(
|
|
1962
|
+
change_dir: Path,
|
|
1963
|
+
*,
|
|
1964
|
+
copy_root: Path | None = None,
|
|
1965
|
+
require_receipt: bool = False,
|
|
1966
|
+
) -> dict[str, Any]:
|
|
1967
|
+
"""Fail closed before freeze/copy when plaintext evidence is unresolved.
|
|
1968
|
+
|
|
1969
|
+
The receipt is deliberately self-excluded from the tree digest. It may
|
|
1970
|
+
therefore bind the exact publishable bytes without creating a recursive
|
|
1971
|
+
digest. Private quarantine paths are evidence metadata only and must be
|
|
1972
|
+
outside both the project/copy roots.
|
|
1973
|
+
"""
|
|
1974
|
+
change_dir = change_dir.expanduser().resolve()
|
|
1975
|
+
copy_root = (copy_root or change_dir).expanduser().resolve()
|
|
1976
|
+
receipt_path = hruntime.sensitive_evidence_receipt_path(change_dir)
|
|
1977
|
+
candidates = hruntime.sensitive_evidence_candidates(change_dir)
|
|
1978
|
+
if candidates:
|
|
1979
|
+
return {
|
|
1980
|
+
"ok": False,
|
|
1981
|
+
"reasonCode": "SENSITIVE_EVIDENCE_UNQUARANTINED",
|
|
1982
|
+
"receiptPath": str(receipt_path),
|
|
1983
|
+
"unresolvedFailures": candidates,
|
|
1984
|
+
"nextAction": "Quarantine the original bytes before archive publication.",
|
|
1985
|
+
}
|
|
1986
|
+
if not receipt_path.is_file():
|
|
1987
|
+
if require_receipt:
|
|
1988
|
+
return {
|
|
1989
|
+
"ok": False,
|
|
1990
|
+
"reasonCode": "SECRET_SCAN_RECEIPT_MISSING",
|
|
1991
|
+
"receiptPath": str(receipt_path),
|
|
1992
|
+
"unresolvedFailures": [],
|
|
1993
|
+
}
|
|
1994
|
+
return {
|
|
1995
|
+
"ok": True,
|
|
1996
|
+
"reasonCode": "SECRET_SCAN_NOT_APPLICABLE",
|
|
1997
|
+
"receiptPath": str(receipt_path),
|
|
1998
|
+
"receiptRequired": False,
|
|
1999
|
+
"unresolvedFailures": [],
|
|
2000
|
+
}
|
|
2001
|
+
try:
|
|
2002
|
+
receipt = read_json(receipt_path)
|
|
2003
|
+
except (OSError, json.JSONDecodeError, TypeError) as exc:
|
|
2004
|
+
return {
|
|
2005
|
+
"ok": False,
|
|
2006
|
+
"reasonCode": "SECRET_SCAN_RECEIPT_INVALID",
|
|
2007
|
+
"receiptPath": str(receipt_path),
|
|
2008
|
+
"error": str(exc),
|
|
2009
|
+
}
|
|
2010
|
+
if not isinstance(receipt, dict):
|
|
2011
|
+
return {
|
|
2012
|
+
"ok": False,
|
|
2013
|
+
"reasonCode": "SECRET_SCAN_RECEIPT_INVALID",
|
|
2014
|
+
"receiptPath": str(receipt_path),
|
|
2015
|
+
"error": "receipt must be an object",
|
|
2016
|
+
}
|
|
2017
|
+
issues: list[dict[str, Any]] = []
|
|
2018
|
+
if receipt.get("schemaVersion") != 1:
|
|
2019
|
+
issues.append({"code": "SECRET_SCAN_SCHEMA_INVALID"})
|
|
2020
|
+
if receipt.get("rulesVersion") != hruntime.SECRET_SCAN_RULES_VERSION:
|
|
2021
|
+
issues.append({"code": "SECRET_SCAN_RULES_MISMATCH"})
|
|
2022
|
+
if receipt.get("changeId") != change_dir.name:
|
|
2023
|
+
issues.append({"code": "SECRET_SCAN_CHANGE_ID_MISMATCH"})
|
|
2024
|
+
if str(receipt.get("status") or "").upper() not in {"OK", "QUARANTINED"}:
|
|
2025
|
+
issues.append({"code": "SENSITIVE_EVIDENCE_QUARANTINE_FAILED"})
|
|
2026
|
+
unresolved = receipt.get("unresolvedFailures")
|
|
2027
|
+
if isinstance(unresolved, list) and unresolved:
|
|
2028
|
+
issues.append({"code": "SENSITIVE_EVIDENCE_QUARANTINE_FAILED", "count": len(unresolved)})
|
|
2029
|
+
elif unresolved not in (None, []):
|
|
2030
|
+
issues.append({"code": "SECRET_SCAN_UNRESOLVED_INVALID"})
|
|
2031
|
+
try:
|
|
2032
|
+
actual_digest = hruntime.publishable_tree_digest(change_dir)
|
|
2033
|
+
except OSError as exc:
|
|
2034
|
+
actual_digest = None
|
|
2035
|
+
issues.append({"code": "SECRET_SCAN_TREE_UNREADABLE", "error": str(exc)})
|
|
2036
|
+
if actual_digest is not None and receipt.get("publishableTreeDigest") != actual_digest:
|
|
2037
|
+
issues.append({
|
|
2038
|
+
"code": "SECRET_SCAN_TREE_DIGEST_MISMATCH",
|
|
2039
|
+
"expected": receipt.get("publishableTreeDigest"),
|
|
2040
|
+
"actual": actual_digest,
|
|
2041
|
+
})
|
|
2042
|
+
if receipt.get("publicationExcluded") is not True:
|
|
2043
|
+
issues.append({"code": "SECRET_SCAN_PUBLICATION_NOT_EXCLUDED"})
|
|
2044
|
+
project_root = find_project_root(change_dir)
|
|
2045
|
+
for entry in receipt.get("entries") or []:
|
|
2046
|
+
if not isinstance(entry, dict):
|
|
2047
|
+
issues.append({"code": "SECRET_SCAN_ENTRY_INVALID"})
|
|
2048
|
+
continue
|
|
2049
|
+
private_raw = entry.get("privatePath")
|
|
2050
|
+
if not isinstance(private_raw, str) or not private_raw.strip():
|
|
2051
|
+
issues.append({"code": "SECRET_SCAN_PRIVATE_PATH_MISSING"})
|
|
2052
|
+
continue
|
|
2053
|
+
private_path = Path(private_raw).expanduser().resolve()
|
|
2054
|
+
if (
|
|
2055
|
+
_path_is_within(private_path, copy_root)
|
|
2056
|
+
or _path_is_within(private_path, project_root)
|
|
2057
|
+
or _path_is_within(private_path, change_dir)
|
|
2058
|
+
):
|
|
2059
|
+
issues.append({
|
|
2060
|
+
"code": "SECRET_SCAN_PRIVATE_PATH_IN_COPY_ROOT",
|
|
2061
|
+
"privatePath": str(private_path),
|
|
2062
|
+
})
|
|
2063
|
+
if not private_path.is_file():
|
|
2064
|
+
issues.append({
|
|
2065
|
+
"code": "SECRET_SCAN_PRIVATE_PATH_MISSING",
|
|
2066
|
+
"privatePath": str(private_path),
|
|
2067
|
+
})
|
|
2068
|
+
source_raw = entry.get("sourcePath")
|
|
2069
|
+
if isinstance(source_raw, str) and source_raw.strip():
|
|
2070
|
+
source_path = (change_dir / source_raw).resolve()
|
|
2071
|
+
if _path_is_within(source_path, change_dir) and source_path.exists():
|
|
2072
|
+
issues.append({
|
|
2073
|
+
"code": "SENSITIVE_EVIDENCE_SOURCE_REMAINS",
|
|
2074
|
+
"sourcePath": source_raw,
|
|
2075
|
+
})
|
|
2076
|
+
return {
|
|
2077
|
+
"ok": not issues,
|
|
2078
|
+
"reasonCode": "SECRET_SCAN_GATE_SATISFIED" if not issues else "SECRET_SCAN_GATE_BLOCKED",
|
|
2079
|
+
"receiptPath": str(receipt_path),
|
|
2080
|
+
"receipt": receipt,
|
|
2081
|
+
"issues": issues,
|
|
2082
|
+
"treeDigest": actual_digest,
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
|
|
1959
2086
|
# ---------------------------------------------------------------------------
|
|
1960
2087
|
# status
|
|
1961
2088
|
# ---------------------------------------------------------------------------
|
|
@@ -2000,6 +2127,22 @@ def check_status(
|
|
|
2000
2127
|
}
|
|
2001
2128
|
)
|
|
2002
2129
|
|
|
2130
|
+
sensitive_gate = validate_sensitive_evidence_publication_gate(
|
|
2131
|
+
change_dir,
|
|
2132
|
+
copy_root=change_dir,
|
|
2133
|
+
require_receipt=False,
|
|
2134
|
+
)
|
|
2135
|
+
checks["sensitive_evidence_publication"] = sensitive_gate
|
|
2136
|
+
if not sensitive_gate.get("ok"):
|
|
2137
|
+
blockers.append({
|
|
2138
|
+
"code": str(sensitive_gate.get("reasonCode") or "SECRET_SCAN_GATE_BLOCKED"),
|
|
2139
|
+
"message": str(
|
|
2140
|
+
sensitive_gate.get("nextAction")
|
|
2141
|
+
or sensitive_gate.get("error")
|
|
2142
|
+
or "sensitive evidence publication gate failed"
|
|
2143
|
+
),
|
|
2144
|
+
})
|
|
2145
|
+
|
|
2003
2146
|
# --- H-4 formal-layer minimum set ---
|
|
2004
2147
|
plans_dir = change_dir / "plans"
|
|
2005
2148
|
plan_files = (
|
|
@@ -2245,6 +2388,14 @@ def check_status(
|
|
|
2245
2388
|
except Exception as exc: # noqa: BLE001 — preflight must not crash status
|
|
2246
2389
|
preflight = {"ok": False, "items": [], "blocking": [], "error": str(exc)}
|
|
2247
2390
|
checks["artifact_preflight"] = preflight
|
|
2391
|
+
if preflight.get("ok") is not True and not preflight.get("blocking"):
|
|
2392
|
+
blockers.append({
|
|
2393
|
+
"code": "artifact-preflight-invalid",
|
|
2394
|
+
"message": str(
|
|
2395
|
+
preflight.get("error")
|
|
2396
|
+
or "artifact event projection or preflight validation failed"
|
|
2397
|
+
),
|
|
2398
|
+
})
|
|
2248
2399
|
for item in preflight.get("blocking") or []:
|
|
2249
2400
|
blockers.append({
|
|
2250
2401
|
"code": "artifact-path-blocking",
|
|
@@ -3890,12 +4041,15 @@ def collect_summary_data(
|
|
|
3890
4041
|
"retention",
|
|
3891
4042
|
"archiveDurability",
|
|
3892
4043
|
"remoteCost",
|
|
4044
|
+
"efficiency",
|
|
3893
4045
|
"projection",
|
|
3894
4046
|
):
|
|
3895
4047
|
if key in existing:
|
|
3896
4048
|
data[key] = _deepcopy_json(existing[key])
|
|
3897
4049
|
if not for_replay or not isinstance(data.get("remoteCost"), dict):
|
|
3898
4050
|
data["remoteCost"] = remote_cost
|
|
4051
|
+
if not for_replay or not isinstance(data.get("efficiency"), dict):
|
|
4052
|
+
data["efficiency"] = heff.collect_efficiency_summary(change_dir)
|
|
3899
4053
|
|
|
3900
4054
|
event_summary = he.build_summary(change_dir, events) if events else {
|
|
3901
4055
|
"ok": True,
|
|
@@ -6461,12 +6615,9 @@ def artifact_preflight(change_dir: Path) -> dict[str, Any]:
|
|
|
6461
6615
|
return {"ok": True, "items": [], "blocking": []}
|
|
6462
6616
|
change_id = change_dir.name
|
|
6463
6617
|
project_root = find_project_root(change_dir)
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
except json.JSONDecodeError:
|
|
6468
|
-
continue
|
|
6469
|
-
if not isinstance(event, dict) or event.get("type") != "artifact":
|
|
6618
|
+
events = he.apply_event_corrections(he.load_events(events_p))
|
|
6619
|
+
for event in events:
|
|
6620
|
+
if event.get("type") != "artifact":
|
|
6470
6621
|
continue
|
|
6471
6622
|
path = str(event.get("path") or "").strip()
|
|
6472
6623
|
kind = str(event.get("kind") or "").strip()
|
|
@@ -6653,9 +6804,19 @@ def evaluate_artifact_budget(change_dir: Path) -> dict[str, Any]:
|
|
|
6653
6804
|
except (OSError, ValueError, json.JSONDecodeError) as exc:
|
|
6654
6805
|
return {
|
|
6655
6806
|
"ok": False,
|
|
6656
|
-
"code": "
|
|
6807
|
+
"code": "ARTIFACT_PREFLIGHT_INVALID",
|
|
6657
6808
|
"message": str(exc),
|
|
6658
6809
|
}
|
|
6810
|
+
if preflight.get("ok") is not True:
|
|
6811
|
+
return {
|
|
6812
|
+
"ok": False,
|
|
6813
|
+
"code": "ARTIFACT_PREFLIGHT_INVALID",
|
|
6814
|
+
"message": str(
|
|
6815
|
+
preflight.get("error")
|
|
6816
|
+
or "artifact event projection or preflight validation failed"
|
|
6817
|
+
),
|
|
6818
|
+
"preflightBlocking": preflight.get("blocking") or [],
|
|
6819
|
+
}
|
|
6659
6820
|
excluded_parts = {
|
|
6660
6821
|
"node_modules",
|
|
6661
6822
|
".venv",
|
|
@@ -6693,7 +6854,7 @@ def evaluate_artifact_budget(change_dir: Path) -> dict[str, Any]:
|
|
|
6693
6854
|
oversized = [
|
|
6694
6855
|
item for item in entries if int(item["bytes"]) > max_file
|
|
6695
6856
|
]
|
|
6696
|
-
ok = total <= max_total and not oversized
|
|
6857
|
+
ok = total <= max_total and not oversized
|
|
6697
6858
|
return {
|
|
6698
6859
|
"ok": ok,
|
|
6699
6860
|
"code": (
|
|
@@ -6722,6 +6883,13 @@ def materialize_repository_artifacts(change_dir: Path) -> dict[str, Any]:
|
|
|
6722
6883
|
change_dir = change_dir.resolve()
|
|
6723
6884
|
project_root = find_project_root(change_dir)
|
|
6724
6885
|
preflight = artifact_preflight(change_dir)
|
|
6886
|
+
if preflight.get("ok") is not True:
|
|
6887
|
+
raise ValueError(
|
|
6888
|
+
str(
|
|
6889
|
+
preflight.get("error")
|
|
6890
|
+
or "artifact event projection or preflight validation failed"
|
|
6891
|
+
)
|
|
6892
|
+
)
|
|
6725
6893
|
copied: list[str] = []
|
|
6726
6894
|
objects: list[dict[str, Any]] = []
|
|
6727
6895
|
bytes_added = 0
|
|
@@ -7295,6 +7463,32 @@ def cmd_finalize(
|
|
|
7295
7463
|
payload["error"] = f"archive target already exists: {archive_dir}"
|
|
7296
7464
|
return 1, payload
|
|
7297
7465
|
|
|
7466
|
+
source_sensitive_gate = validate_sensitive_evidence_publication_gate(
|
|
7467
|
+
original_change_dir,
|
|
7468
|
+
copy_root=original_change_dir,
|
|
7469
|
+
require_receipt=False,
|
|
7470
|
+
)
|
|
7471
|
+
payload["steps"]["sensitive_evidence_source_gate"] = source_sensitive_gate
|
|
7472
|
+
if not source_sensitive_gate.get("ok"):
|
|
7473
|
+
payload["error"] = str(
|
|
7474
|
+
source_sensitive_gate.get("nextAction")
|
|
7475
|
+
or source_sensitive_gate.get("error")
|
|
7476
|
+
or "sensitive evidence publication gate failed"
|
|
7477
|
+
)
|
|
7478
|
+
payload["issues"] = [
|
|
7479
|
+
{
|
|
7480
|
+
"code": str(
|
|
7481
|
+
source_sensitive_gate.get("reasonCode")
|
|
7482
|
+
or "SECRET_SCAN_GATE_BLOCKED"
|
|
7483
|
+
),
|
|
7484
|
+
"severity": "error",
|
|
7485
|
+
"message": payload["error"],
|
|
7486
|
+
}
|
|
7487
|
+
]
|
|
7488
|
+
payload["original_preserved"] = original_change_dir.is_dir()
|
|
7489
|
+
payload["finalStatus"] = "FAIL"
|
|
7490
|
+
return 1, payload
|
|
7491
|
+
|
|
7298
7492
|
exact_byte = check_archive_exact_byte_policy(project_root)
|
|
7299
7493
|
payload["steps"]["archive_exact_byte"] = exact_byte
|
|
7300
7494
|
if not exact_byte["ok"]:
|
|
@@ -7303,7 +7497,13 @@ def cmd_finalize(
|
|
|
7303
7497
|
artifact_budget = evaluate_artifact_budget(original_change_dir)
|
|
7304
7498
|
payload["steps"]["artifact_budget"] = artifact_budget
|
|
7305
7499
|
if not artifact_budget.get("ok"):
|
|
7306
|
-
|
|
7500
|
+
if artifact_budget.get("code") == "ARTIFACT_PREFLIGHT_INVALID":
|
|
7501
|
+
payload["error"] = str(
|
|
7502
|
+
artifact_budget.get("message")
|
|
7503
|
+
or "artifact validation failed before staging"
|
|
7504
|
+
)
|
|
7505
|
+
else:
|
|
7506
|
+
payload["error"] = "artifact budget exceeded before staging"
|
|
7307
7507
|
payload["issues"] = [
|
|
7308
7508
|
{
|
|
7309
7509
|
"code": str(
|
|
@@ -7376,6 +7576,38 @@ def cmd_finalize(
|
|
|
7376
7576
|
work_dir = operation_temp_dir
|
|
7377
7577
|
before_manifest: dict[str, Any] | None = None
|
|
7378
7578
|
|
|
7579
|
+
# A source tree without sensitive evidence still receives a digest-bound
|
|
7580
|
+
# receipt in the isolated staging tree. This keeps legacy archives
|
|
7581
|
+
# compatible while making every published archive auditable.
|
|
7582
|
+
try:
|
|
7583
|
+
staged_receipt = hruntime.sensitive_evidence_receipt_path(work_dir)
|
|
7584
|
+
if not staged_receipt.is_file():
|
|
7585
|
+
hruntime.ensure_sensitive_evidence_scan_receipt(work_dir)
|
|
7586
|
+
staged_sensitive_gate = validate_sensitive_evidence_publication_gate(
|
|
7587
|
+
work_dir,
|
|
7588
|
+
copy_root=work_dir,
|
|
7589
|
+
require_receipt=True,
|
|
7590
|
+
)
|
|
7591
|
+
payload["steps"]["sensitive_evidence_publication"] = staged_sensitive_gate
|
|
7592
|
+
if not staged_sensitive_gate.get("ok"):
|
|
7593
|
+
payload["error"] = "sensitive evidence publication gate failed before freeze"
|
|
7594
|
+
payload["issues"] = [
|
|
7595
|
+
{
|
|
7596
|
+
"code": str(
|
|
7597
|
+
staged_sensitive_gate.get("reasonCode")
|
|
7598
|
+
or "SECRET_SCAN_GATE_BLOCKED"
|
|
7599
|
+
),
|
|
7600
|
+
"severity": "error",
|
|
7601
|
+
"message": payload["error"],
|
|
7602
|
+
}
|
|
7603
|
+
]
|
|
7604
|
+
_restore_finalize_failure()
|
|
7605
|
+
return 1, payload
|
|
7606
|
+
except (OSError, ValueError, json.JSONDecodeError) as exc:
|
|
7607
|
+
payload["error"] = f"sensitive evidence publication gate failed: {exc}"
|
|
7608
|
+
_restore_finalize_failure()
|
|
7609
|
+
return 1, payload
|
|
7610
|
+
|
|
7379
7611
|
if split_state_dir is not None and split_state_dir.is_dir():
|
|
7380
7612
|
_merge_runtime_state(split_state_dir, work_dir)
|
|
7381
7613
|
payload["steps"]["split_state_merge"] = {
|
|
@@ -7474,19 +7706,36 @@ def cmd_finalize(
|
|
|
7474
7706
|
"blockingCount": len(preflight.get("blocking") or []),
|
|
7475
7707
|
"itemsCount": len(preflight.get("items") or []),
|
|
7476
7708
|
}
|
|
7477
|
-
if preflight.get("
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7709
|
+
if preflight.get("ok") is not True:
|
|
7710
|
+
blocking_paths = preflight.get("blocking") or []
|
|
7711
|
+
if blocking_paths:
|
|
7712
|
+
payload["error"] = (
|
|
7713
|
+
f"artifact preflight blocking: "
|
|
7714
|
+
f"{len(blocking_paths)} path(s) cannot be archived"
|
|
7715
|
+
)
|
|
7716
|
+
payload["issues"] = [
|
|
7717
|
+
{
|
|
7718
|
+
"code": "ARTIFACT_PATH_BLOCKING",
|
|
7719
|
+
"severity": "error",
|
|
7720
|
+
"message": f"{item.get('path', '')}: {item.get('reason', 'blocking')}",
|
|
7721
|
+
}
|
|
7722
|
+
for item in blocking_paths
|
|
7723
|
+
]
|
|
7724
|
+
else:
|
|
7725
|
+
payload["error"] = (
|
|
7726
|
+
"artifact preflight invalid: "
|
|
7727
|
+
+ str(
|
|
7728
|
+
preflight.get("error")
|
|
7729
|
+
or "artifact event projection or preflight validation failed"
|
|
7730
|
+
)
|
|
7731
|
+
)
|
|
7732
|
+
payload["issues"] = [
|
|
7733
|
+
{
|
|
7734
|
+
"code": "ARTIFACT_PREFLIGHT_INVALID",
|
|
7735
|
+
"severity": "error",
|
|
7736
|
+
"message": payload["error"],
|
|
7737
|
+
}
|
|
7738
|
+
]
|
|
7490
7739
|
_restore_finalize_failure()
|
|
7491
7740
|
payload["warnings"] = warnings
|
|
7492
7741
|
payload["ok"] = False
|