harnery 0.38.0 → 0.40.0
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/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +32 -8
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +97 -6
- package/dist/commands/backup.d.ts +16 -0
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +239 -33
- package/dist/commands/browse.d.ts +8 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +466 -231
- package/dist/commands/diagnostics.d.ts.map +1 -1
- package/dist/commands/diagnostics.js +6 -3
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +20 -4
- package/dist/commands/qa-run.d.ts.map +1 -1
- package/dist/commands/qa-run.js +26 -3
- package/dist/commands/qa-status.d.ts.map +1 -1
- package/dist/commands/qa-status.js +7 -2
- package/dist/commands/resources.d.ts.map +1 -1
- package/dist/commands/resources.js +23 -3
- package/dist/commands/review-pack.d.ts.map +1 -1
- package/dist/commands/review-pack.js +98 -23
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +2 -2
- package/dist/core/adapters/profiles.d.ts +1 -1
- package/dist/core/agents/canonical-emit.d.ts +3 -2
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +2 -0
- package/dist/core/agents/cli.js +13 -6
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +5 -3
- package/dist/core/agents/live-lifecycle-v3.d.ts +2 -2
- package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.d.ts +7 -5
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +63 -8
- package/dist/core/agents/session-finalizer-v3.d.ts +2 -2
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.d.ts +3 -3
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +2 -1
- package/dist/core/agents/state/names.d.ts +35 -2
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +80 -5
- package/dist/core/agents/state/stale-sweep.d.ts +2 -1
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +23 -6
- package/dist/core/agents/turn-elapsed.d.ts +51 -0
- package/dist/core/agents/turn-elapsed.d.ts.map +1 -0
- package/dist/core/agents/turn-elapsed.js +91 -0
- package/dist/core/artifacts/activity.d.ts +14 -0
- package/dist/core/artifacts/activity.d.ts.map +1 -0
- package/dist/core/artifacts/activity.js +52 -0
- package/dist/core/artifacts/delivery-card.d.ts +39 -0
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -0
- package/dist/core/artifacts/delivery-card.js +282 -0
- package/dist/core/artifacts/index.d.ts +42 -7
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +288 -76
- package/dist/core/artifacts/mutation-lock.d.ts +2 -0
- package/dist/core/artifacts/mutation-lock.d.ts.map +1 -0
- package/dist/core/artifacts/mutation-lock.js +91 -0
- package/dist/core/backup/host-snapshot.d.ts +18 -0
- package/dist/core/backup/host-snapshot.d.ts.map +1 -0
- package/dist/core/backup/host-snapshot.js +64 -0
- package/dist/core/config.d.ts +20 -5
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +44 -10
- package/dist/core/diagnostics/advice.d.ts +38 -3
- package/dist/core/diagnostics/advice.d.ts.map +1 -1
- package/dist/core/diagnostics/advice.js +103 -99
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +111 -47
- package/dist/core/diagnostics/comparison.d.ts.map +1 -1
- package/dist/core/diagnostics/comparison.js +3 -2
- package/dist/core/diagnostics/contract.d.ts +15 -31
- package/dist/core/diagnostics/contract.d.ts.map +1 -1
- package/dist/core/diagnostics/contract.js +2 -5
- package/dist/core/diagnostics/index.d.ts +2 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -1
- package/dist/core/diagnostics/index.js +2 -0
- package/dist/core/diagnostics/pressure-contract.d.ts +260 -0
- package/dist/core/diagnostics/pressure-contract.d.ts.map +1 -0
- package/dist/core/diagnostics/pressure-contract.js +70 -0
- package/dist/core/diagnostics/pressure.d.ts +25 -0
- package/dist/core/diagnostics/pressure.d.ts.map +1 -0
- package/dist/core/diagnostics/pressure.js +1138 -0
- package/dist/core/diagnostics/replay.d.ts.map +1 -1
- package/dist/core/diagnostics/replay.js +90 -10
- package/dist/core/events/v3/adapter-id.d.ts +6 -0
- package/dist/core/events/v3/adapter-id.d.ts.map +1 -0
- package/dist/core/events/v3/adapter-id.js +7 -0
- package/dist/core/events/v3/archive-retention.d.ts.map +1 -1
- package/dist/core/events/v3/archive-retention.js +3 -2
- package/dist/core/events/v3/bootstrap.d.ts +41 -4
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +120 -17
- package/dist/core/events/v3/capabilities.d.ts +16 -9
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +37 -2
- package/dist/core/events/v3/capability-drift.d.ts +2 -2
- package/dist/core/events/v3/capability-drift.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.d.ts +48 -5
- package/dist/core/events/v3/control-witness.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.js +91 -36
- package/dist/core/events/v3/control.d.ts.map +1 -1
- package/dist/core/events/v3/control.js +22 -2
- package/dist/core/events/v3/index.d.ts +2 -1
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +2 -1
- package/dist/core/events/v3/live-feed.d.ts +7 -1
- package/dist/core/events/v3/live-feed.d.ts.map +1 -1
- package/dist/core/events/v3/live-feed.js +21 -3
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +10 -2
- package/dist/core/events/v3/producers/command-recorder.d.ts +2 -2
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +2 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +2 -2
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +2 -1
- package/dist/core/events/v3/producers/hook-base.d.ts +2 -2
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +15 -5
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook.js +17 -4
- package/dist/core/events/v3/producers/intake.d.ts +4 -4
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +3 -2
- package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -1
- package/dist/core/events/v3/producers/producer-state-observer.js +2 -1
- package/dist/core/events/v3/producers/recorder.d.ts +16 -5
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +31 -9
- package/dist/core/events/v3/reader.d.ts.map +1 -1
- package/dist/core/events/v3/reader.js +10 -13
- package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
- package/dist/core/events/v3/runtime-build.js +3 -2
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +2 -2
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/turn-telemetry.d.ts +2 -2
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.d.ts +16 -14
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +36 -38
- package/dist/core/hooks/backup-schedule.d.ts +34 -0
- package/dist/core/hooks/backup-schedule.d.ts.map +1 -0
- package/dist/core/hooks/backup-schedule.js +114 -0
- package/dist/core/hooks/cli.js +61 -18
- package/dist/core/hooks/codex-wsl-bridge.d.ts +2 -0
- package/dist/core/hooks/codex-wsl-bridge.d.ts.map +1 -1
- package/dist/core/hooks/codex-wsl-bridge.js +18 -4
- package/dist/core/hooks/index.d.ts +1 -0
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js +1 -0
- package/dist/core/hooks/prompt-context/contract.d.ts +61 -0
- package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/contract.js +102 -0
- package/dist/core/hooks/prompt-context/index.d.ts +5 -0
- package/dist/core/hooks/prompt-context/index.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/index.js +2 -0
- package/dist/core/hooks/prompt-context/runner.d.ts +24 -0
- package/dist/core/hooks/prompt-context/runner.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/runner.js +249 -0
- package/dist/core/qa-artifacts.d.ts +3 -0
- package/dist/core/qa-artifacts.d.ts.map +1 -1
- package/dist/core/qa-artifacts.js +25 -3
- package/dist/core/resources/contract.d.ts +69 -3
- package/dist/core/resources/contract.d.ts.map +1 -1
- package/dist/core/resources/contract.js +1 -1
- package/dist/core/resources/index.d.ts +1 -0
- package/dist/core/resources/index.d.ts.map +1 -1
- package/dist/core/resources/index.js +1 -0
- package/dist/core/resources/native.d.ts +36 -0
- package/dist/core/resources/native.d.ts.map +1 -0
- package/dist/core/resources/native.js +418 -0
- package/dist/core/resources/sampler.d.ts +2 -0
- package/dist/core/resources/sampler.d.ts.map +1 -1
- package/dist/core/resources/sampler.js +31 -1
- package/dist/core/resources/status.d.ts +61 -0
- package/dist/core/resources/status.d.ts.map +1 -0
- package/dist/core/resources/status.js +536 -0
- package/dist/core/resources/system.d.ts +27 -0
- package/dist/core/resources/system.d.ts.map +1 -0
- package/dist/core/resources/system.js +439 -0
- package/dist/core/semantic/contract.d.ts +13 -13
- package/dist/core/semantic/service.d.ts +2 -0
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +27 -4
- package/dist/core/storage/builtins.js +41 -0
- package/dist/core/supervisor/contract.d.ts +41 -3
- package/dist/core/supervisor/contract.d.ts.map +1 -1
- package/dist/core/supervisor/contract.js +3 -2
- package/dist/core/supervisor/findings.d.ts +3 -0
- package/dist/core/supervisor/findings.d.ts.map +1 -1
- package/dist/core/supervisor/findings.js +88 -0
- package/dist/core/supervisor/history.d.ts.map +1 -1
- package/dist/core/supervisor/history.js +14 -0
- package/dist/core/supervisor/ledger-state.d.ts +55 -0
- package/dist/core/supervisor/ledger-state.d.ts.map +1 -0
- package/dist/core/supervisor/ledger-state.js +0 -0
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +120 -7
- package/dist/core/supervisor/storage.d.ts +3 -1
- package/dist/core/supervisor/storage.d.ts.map +1 -1
- package/dist/core/supervisor/storage.js +4 -0
- package/dist/core/workflow/admission.d.ts +3 -0
- package/dist/core/workflow/admission.d.ts.map +1 -1
- package/dist/core/workflow/admission.js +28 -16
- package/dist/core/workflow/engine.js +2 -2
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +6 -1
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +4 -3
- package/dist/lib/browser/capture-fidelity.d.ts +7 -0
- package/dist/lib/browser/capture-fidelity.d.ts.map +1 -1
- package/dist/lib/browser/capture-fidelity.js +17 -0
- package/dist/lib/browser/client.d.ts +9 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +85 -37
- package/dist/lib/browser/index.d.ts +3 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -1
- package/dist/lib/browser/page-review-budget.d.ts +13 -0
- package/dist/lib/browser/page-review-budget.d.ts.map +1 -0
- package/dist/lib/browser/page-review-budget.js +251 -0
- package/dist/lib/browser/page-review-contracts.d.ts +127 -0
- package/dist/lib/browser/page-review-contracts.d.ts.map +1 -0
- package/dist/lib/browser/page-review-contracts.js +5 -0
- package/dist/lib/browser/page-review-evidence.d.ts +48 -0
- package/dist/lib/browser/page-review-evidence.d.ts.map +1 -0
- package/dist/lib/browser/page-review-evidence.js +340 -0
- package/dist/lib/browser/page-review-judge.d.ts +1 -1
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +46 -38
- package/dist/lib/browser/page-review-pack.d.ts +44 -22
- package/dist/lib/browser/page-review-pack.d.ts.map +1 -1
- package/dist/lib/browser/page-review-pack.js +116 -36
- package/dist/lib/browser/page-review-source.d.ts +12 -0
- package/dist/lib/browser/page-review-source.d.ts.map +1 -0
- package/dist/lib/browser/page-review-source.js +22 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +35 -9
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run-contracts.js +48 -14
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +215 -68
- package/dist/lib/browser/qa-snapshot.d.ts +6 -0
- package/dist/lib/browser/qa-snapshot.d.ts.map +1 -1
- package/dist/lib/browser/qa-snapshot.js +259 -48
- package/dist/lib/browser/review-capture-transaction.d.ts +13 -0
- package/dist/lib/browser/review-capture-transaction.d.ts.map +1 -0
- package/dist/lib/browser/review-capture-transaction.js +79 -0
- package/dist/lib/browser/standalone-html.d.ts.map +1 -1
- package/dist/lib/browser/standalone-html.js +4 -2
- package/dist/lib/browser/thumbnail-association.d.ts +34 -0
- package/dist/lib/browser/thumbnail-association.d.ts.map +1 -0
- package/dist/lib/browser/thumbnail-association.js +158 -0
- package/dist/lib/browser/tiling.d.ts +30 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -1
- package/dist/lib/browser/tiling.js +38 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
- package/dist/lib/docs-metadata-managed.js +4 -1
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +7 -1
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +1 -0
- package/dist/lib/local-file-url.d.ts +12 -0
- package/dist/lib/local-file-url.d.ts.map +1 -1
- package/dist/lib/local-file-url.js +16 -2
- package/dist/lib/tunnel/state.d.ts +19 -4
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +53 -13
- package/package.json +7 -4
- package/schemas/config.schema.json +69 -2
- package/src/commands/agents.ts +42 -9
- package/src/commands/artifacts.ts +130 -6
- package/src/commands/backup.ts +287 -34
- package/src/commands/browse.ts +564 -267
- package/src/commands/diagnostics.ts +6 -3
- package/src/commands/ledger-v3.ts +20 -3
- package/src/commands/qa-run.ts +37 -3
- package/src/commands/qa-status.ts +11 -2
- package/src/commands/resources.ts +23 -3
- package/src/commands/review-pack.ts +165 -62
- package/src/commands/tunnel.ts +2 -1
- package/src/core/agents/canonical-emit.ts +4 -2
- package/src/core/agents/cli.ts +14 -6
- package/src/core/agents/live-authority-v3.ts +7 -3
- package/src/core/agents/live-lifecycle-v3.ts +2 -2
- package/src/core/agents/render/prompt-context.ts +68 -14
- package/src/core/agents/session-finalizer-v3.ts +2 -2
- package/src/core/agents/state/live-coordination-view.ts +4 -4
- package/src/core/agents/state/names.ts +92 -7
- package/src/core/agents/state/stale-sweep.ts +22 -8
- package/src/core/agents/turn-elapsed.ts +135 -0
- package/src/core/artifacts/activity.ts +71 -0
- package/src/core/artifacts/delivery-card.ts +375 -0
- package/src/core/artifacts/index.ts +385 -91
- package/src/core/artifacts/mutation-lock.ts +106 -0
- package/src/core/backup/host-snapshot.ts +76 -0
- package/src/core/config.ts +66 -13
- package/src/core/diagnostics/advice.ts +148 -120
- package/src/core/diagnostics/bundle.ts +138 -52
- package/src/core/diagnostics/comparison.ts +6 -2
- package/src/core/diagnostics/contract.ts +39 -42
- package/src/core/diagnostics/index.ts +2 -0
- package/src/core/diagnostics/pressure-contract.ts +294 -0
- package/src/core/diagnostics/pressure.ts +1361 -0
- package/src/core/diagnostics/replay.ts +116 -11
- package/src/core/events/v3/adapter-id.ts +12 -0
- package/src/core/events/v3/archive-retention.ts +3 -6
- package/src/core/events/v3/bootstrap.ts +163 -16
- package/src/core/events/v3/capabilities.ts +75 -25
- package/src/core/events/v3/capability-drift.ts +2 -2
- package/src/core/events/v3/control-witness.ts +172 -41
- package/src/core/events/v3/control.ts +34 -2
- package/src/core/events/v3/index.ts +3 -0
- package/src/core/events/v3/live-feed.ts +23 -5
- package/src/core/events/v3/live-routing.ts +14 -2
- package/src/core/events/v3/producers/command-recorder.ts +4 -4
- package/src/core/events/v3/producers/coordination-recorder.ts +4 -4
- package/src/core/events/v3/producers/hook-base.ts +21 -16
- package/src/core/events/v3/producers/hook.ts +21 -4
- package/src/core/events/v3/producers/intake.ts +6 -6
- package/src/core/events/v3/producers/producer-state-observer.ts +2 -1
- package/src/core/events/v3/producers/recorder.ts +50 -21
- package/src/core/events/v3/reader.ts +14 -13
- package/src/core/events/v3/runtime-build.ts +3 -2
- package/src/core/events/v3/runtime-telemetry-capabilities.ts +3 -3
- package/src/core/events/v3/turn-telemetry.ts +4 -4
- package/src/core/hooks/adapter/output.ts +50 -36
- package/src/core/hooks/backup-schedule.ts +147 -0
- package/src/core/hooks/cli.ts +65 -14
- package/src/core/hooks/codex-wsl-bridge.ts +21 -5
- package/src/core/hooks/index.ts +1 -0
- package/src/core/hooks/prompt-context/contract.ts +177 -0
- package/src/core/hooks/prompt-context/index.ts +22 -0
- package/src/core/hooks/prompt-context/runner.ts +303 -0
- package/src/core/qa-artifacts.ts +29 -3
- package/src/core/resources/contract.ts +76 -3
- package/src/core/resources/index.ts +1 -0
- package/src/core/resources/native.ts +481 -0
- package/src/core/resources/sampler.ts +46 -1
- package/src/core/resources/status.ts +717 -0
- package/src/core/resources/system.ts +530 -0
- package/src/core/semantic/service.ts +37 -3
- package/src/core/storage/builtins.ts +41 -0
- package/src/core/supervisor/contract.ts +45 -3
- package/src/core/supervisor/findings.ts +159 -0
- package/src/core/supervisor/history.ts +15 -0
- package/src/core/supervisor/ledger-state.ts +0 -0
- package/src/core/supervisor/service.ts +133 -5
- package/src/core/supervisor/storage.ts +7 -0
- package/src/core/workflow/admission.ts +33 -17
- package/src/core/workflow/engine.ts +2 -2
- package/src/core/workflow/live-session-v3.ts +6 -8
- package/src/core/workflow/proof.ts +4 -3
- package/src/lib/browser/capture-fidelity.ts +23 -0
- package/src/lib/browser/client.ts +96 -44
- package/src/lib/browser/index.ts +15 -1
- package/src/lib/browser/page-review-budget.ts +309 -0
- package/src/lib/browser/page-review-contracts.ts +129 -0
- package/src/lib/browser/page-review-evidence.ts +465 -0
- package/src/lib/browser/page-review-judge.ts +56 -40
- package/src/lib/browser/page-review-pack.ts +181 -43
- package/src/lib/browser/page-review-source.ts +30 -0
- package/src/lib/browser/qa-run-contracts.ts +62 -18
- package/src/lib/browser/qa-run.ts +259 -71
- package/src/lib/browser/qa-snapshot.ts +289 -48
- package/src/lib/browser/review-capture-transaction.ts +106 -0
- package/src/lib/browser/standalone-html.ts +4 -2
- package/src/lib/browser/thumbnail-association.ts +190 -0
- package/src/lib/browser/tiling.ts +63 -0
- package/src/lib/docs-metadata-managed.ts +4 -1
- package/src/lib/identities/assume.ts +12 -4
- package/src/lib/instructions/templates.ts +1 -0
- package/src/lib/local-file-url.ts +17 -2
- package/src/lib/tunnel/state.ts +70 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qa-run-contracts.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-run-contracts.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1D,eAAO,MAAM,yBAAyB,EAAG,CAAU,CAAC;AACpD,eAAO,MAAM,4BAA4B,EAAG,CAAU,CAAC;AAEvD;;;;yBAIyB;AACzB,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEtD,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC3B;4DACwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd;4EACwE;IACxE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;4BAE4B;AAC5B,MAAM,WAAW,UAAU;IACzB,2EAA2E;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX,sFAAsF;IACtF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;qEACqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;iFAC6E;IAC7E,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B;0EACsE;IACtE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;4CACwC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4DAA4D;IAC5D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;4DAGwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB
|
|
1
|
+
{"version":3,"file":"qa-run-contracts.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-run-contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -162,6 +162,18 @@ export function validateQaRunJob(value) {
|
|
|
162
162
|
}
|
|
163
163
|
if (job.policy !== undefined) {
|
|
164
164
|
const p = job.policy;
|
|
165
|
+
if (p === null || typeof p !== "object" || Array.isArray(p)) {
|
|
166
|
+
errors.push("policy must be an object");
|
|
167
|
+
}
|
|
168
|
+
if (p?.accept_dispositions !== undefined && typeof p.accept_dispositions !== "boolean") {
|
|
169
|
+
errors.push("policy.accept_dispositions must be a boolean");
|
|
170
|
+
}
|
|
171
|
+
if (p?.critique_tile_budget !== undefined) {
|
|
172
|
+
const n = p.critique_tile_budget;
|
|
173
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n < 8 || n > 400) {
|
|
174
|
+
errors.push("policy.critique_tile_budget must be an integer between 8 and 400");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
165
177
|
if (p?.command_concurrency !== undefined) {
|
|
166
178
|
const n = p.command_concurrency;
|
|
167
179
|
if (typeof n !== "number" || !Number.isInteger(n) || n < 1 || n > 8) {
|
|
@@ -182,8 +194,8 @@ export function validateQaRunJob(value) {
|
|
|
182
194
|
}
|
|
183
195
|
if (p?.critique_max_tiles !== undefined) {
|
|
184
196
|
const n = p.critique_max_tiles;
|
|
185
|
-
if (typeof n !== "number" || !Number.isInteger(n) || n < 1 || n >
|
|
186
|
-
errors.push("policy.critique_max_tiles must be an integer between 1 and
|
|
197
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n < 1 || n > 400) {
|
|
198
|
+
errors.push("policy.critique_max_tiles must be an integer between 1 and 400");
|
|
187
199
|
}
|
|
188
200
|
}
|
|
189
201
|
if (p?.critique_pool !== undefined) {
|
|
@@ -213,7 +225,10 @@ export function contextIdFor(context) {
|
|
|
213
225
|
/**
|
|
214
226
|
* Merge planner-manifest coverage with the job's extra contexts. The manifest
|
|
215
227
|
* is the floor: its contexts always run, in manifest order, and a job can only
|
|
216
|
-
* append
|
|
228
|
+
* append coverage or supply setup arguments for an exactly matching context.
|
|
229
|
+
* IDs and rendering identities must agree; aliases are rejected rather than
|
|
230
|
+
* silently losing a setup or leaving a check pointed at an absent context.
|
|
231
|
+
* The union construction makes narrowing impossible by design; the
|
|
217
232
|
* returned list is what the runner executes and what the result reports.
|
|
218
233
|
*/
|
|
219
234
|
export function mergeCoverage(manifest, job) {
|
|
@@ -223,14 +238,31 @@ export function mergeCoverage(manifest, job) {
|
|
|
223
238
|
theme: context.theme,
|
|
224
239
|
state: context.state,
|
|
225
240
|
}));
|
|
226
|
-
const
|
|
241
|
+
const identity = (context) => JSON.stringify([context.viewport, context.theme, context.state]);
|
|
242
|
+
const byId = new Map(merged.map((context) => [context.id, context]));
|
|
243
|
+
const byRender = new Map(merged.map((context) => [identity(context), context]));
|
|
244
|
+
const jobIds = new Set();
|
|
227
245
|
for (const context of job.contexts ?? []) {
|
|
228
|
-
|
|
229
|
-
|
|
246
|
+
if (jobIds.has(context.id))
|
|
247
|
+
throw new Error(`Duplicate QA context ID: ${context.id}`);
|
|
248
|
+
jobIds.add(context.id);
|
|
249
|
+
const existingId = byId.get(context.id);
|
|
250
|
+
const existingRender = byRender.get(identity(context));
|
|
251
|
+
if (existingId || existingRender) {
|
|
252
|
+
if (!existingId || existingId !== existingRender) {
|
|
253
|
+
throw new Error(`Conflicting QA context ID or rendering identity: ${context.id}`);
|
|
254
|
+
}
|
|
255
|
+
if (context.args !== undefined)
|
|
256
|
+
existingId.args = [...context.args];
|
|
230
257
|
continue;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
258
|
+
}
|
|
259
|
+
const added = {
|
|
260
|
+
...context,
|
|
261
|
+
...(context.args !== undefined ? { args: [...context.args] } : {}),
|
|
262
|
+
};
|
|
263
|
+
byId.set(added.id, added);
|
|
264
|
+
byRender.set(identity(added), added);
|
|
265
|
+
merged.push(added);
|
|
234
266
|
}
|
|
235
267
|
return merged;
|
|
236
268
|
}
|
|
@@ -266,12 +298,14 @@ function canonicalize(value) {
|
|
|
266
298
|
return value;
|
|
267
299
|
}
|
|
268
300
|
/** SHA-256 hex digest over the effective validated job (after the CLI merges
|
|
269
|
-
* its authoritative `target` and `mode`).
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* them would make the same job file verify differently across invocations. */
|
|
301
|
+
* its authoritative `target` and `mode`). Runtime policy knobs are excluded.
|
|
302
|
+
* Disposition acceptance changes what can establish a pass, so enabling it
|
|
303
|
+
* is identity-bearing; an ordinary run cannot verify as an accepting run. */
|
|
273
304
|
export function computeJobDigest(job) {
|
|
274
|
-
const { policy
|
|
305
|
+
const { policy, ...rest } = job;
|
|
306
|
+
const identityBearing = policy?.accept_dispositions === true
|
|
307
|
+
? { ...rest, policy: { accept_dispositions: true } }
|
|
308
|
+
: rest;
|
|
275
309
|
return createHash("sha256")
|
|
276
310
|
.update(JSON.stringify(canonicalize(identityBearing)))
|
|
277
311
|
.digest("hex");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qa-run.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-run.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,KAAK,gBAAgB,EAA2B,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"qa-run.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,11 +16,13 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "
|
|
|
16
16
|
import { cpus, freemem, loadavg, totalmem } from "node:os";
|
|
17
17
|
import { basename, join } from "node:path";
|
|
18
18
|
import { DEFAULT_CRITIQUE_RUBRIC } from "./critique.js";
|
|
19
|
+
import { allocateTileBudget, capturePlanDigest, validatePageReviewCapturePlan, } from "./page-review-budget.js";
|
|
20
|
+
import { PAGE_REVIEW_DEFAULT_TILE_BUDGET, } from "./page-review-contracts.js";
|
|
21
|
+
import { applyPackReviewDecisions, buildPackNativeEvidence } from "./page-review-evidence.js";
|
|
19
22
|
import { judgePageReviewPack, toCritiqueRecords } from "./page-review-judge.js";
|
|
20
|
-
import { finalizePageReviewPack, gateHitsFromEnvelope, PAGE_REVIEW_DEFAULT_RETENTION_MINUTES, PAGE_REVIEW_FINDINGS_FILENAME, PAGE_REVIEW_PACK_DIRNAME, PAGE_REVIEW_PACK_SCHEMA, PAGE_REVIEW_REVIEW_FILENAME, readPackContext, readPackDom,
|
|
21
|
-
import { QA_CRITIQUE_CONTRACT_VERSION, rubricDigest } from "./qa-reuse.js";
|
|
23
|
+
import { finalizePageReviewPack, gateHitsFromEnvelope, PAGE_REVIEW_DEFAULT_RETENTION_MINUTES, PAGE_REVIEW_FINDINGS_FILENAME, PAGE_REVIEW_PACK_DIRNAME, PAGE_REVIEW_PACK_SCHEMA, PAGE_REVIEW_REVIEW_FILENAME, readPackContext, readPackDom, readPackManifest, readPackSignature, readPackTiles, } from "./page-review-pack.js";
|
|
22
24
|
import { computeJobDigest, computeVerdict, mergeCoverage, QA_RUN_RESULT_SCHEMA_VERSION, QA_RUN_STATUS_SCHEMA_VERSION, } from "./qa-run-contracts.js";
|
|
23
|
-
import { saveQaSnapshot } from "./qa-snapshot.js";
|
|
25
|
+
import { loadReviewDecisions, saveQaSnapshot } from "./qa-snapshot.js";
|
|
24
26
|
/** Set on the runner's own environment before the host's critique provider is
|
|
25
27
|
* loaded for the judge stage, unless the job permits metered critique: the
|
|
26
28
|
* provider must stay on subscription-backed headless harnesses and surface
|
|
@@ -76,7 +78,6 @@ const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
|
|
|
76
78
|
const DEFAULT_RUN_DEADLINE_MS = 900_000;
|
|
77
79
|
const DEFAULT_COMMAND_CONCURRENCY = 2;
|
|
78
80
|
/** Gate-hit rectangles forwarded to one context's capture child (`--review-pack-hit-rect`). */
|
|
79
|
-
const REVIEW_PACK_HIT_RECTS_PER_CONTEXT = 50;
|
|
80
81
|
const EXEC_MAX_BUFFER = 16 * 1024 * 1024;
|
|
81
82
|
/** The planner's deterministic vocabulary is an executable contract, not a
|
|
82
83
|
* report-only hint. A job may add checks, but these arguments always run for
|
|
@@ -617,12 +618,22 @@ export async function runQaMatrix(options) {
|
|
|
617
618
|
ctx.viewport,
|
|
618
619
|
...(ctx.theme === "dark" ? ["--color-scheme", "dark"] : []),
|
|
619
620
|
...(ctx.args ?? []),
|
|
621
|
+
...(job.interaction_states ?? [])
|
|
622
|
+
.filter((state) => state.name === ctx.state)
|
|
623
|
+
.flatMap((state) => [
|
|
624
|
+
...state.setup,
|
|
625
|
+
...state.assertions.flatMap((assertion) => ["--assert", assertion]),
|
|
626
|
+
"--assert-fail",
|
|
627
|
+
]),
|
|
620
628
|
];
|
|
621
629
|
// The planner's tile ceiling and every critique child must agree on the
|
|
622
630
|
// per-context band cap, or the predicted cost and the real coverage drift.
|
|
623
|
-
const critiqueMaxTilesArgs =
|
|
624
|
-
|
|
625
|
-
|
|
631
|
+
const critiqueMaxTilesArgs = [
|
|
632
|
+
"--check-critique-max-tiles",
|
|
633
|
+
String(job.policy?.critique_max_tiles ??
|
|
634
|
+
job.policy?.critique_tile_budget ??
|
|
635
|
+
PAGE_REVIEW_DEFAULT_TILE_BUDGET),
|
|
636
|
+
];
|
|
626
637
|
// ------------------------------------------------------------------ plan
|
|
627
638
|
const planArgv = [
|
|
628
639
|
...browseArgv,
|
|
@@ -707,6 +718,37 @@ export async function runQaMatrix(options) {
|
|
|
707
718
|
}
|
|
708
719
|
return finalize();
|
|
709
720
|
}
|
|
721
|
+
// The planning render and capture must use the same native band geometry.
|
|
722
|
+
// Load the provider's pixel budget before gates, without making model calls.
|
|
723
|
+
const visual = manifest.checks.visual;
|
|
724
|
+
const runsVisual = visual !== "none";
|
|
725
|
+
const priorHeadlessOnly = process.env[QA_RUN_HEADLESS_ONLY_ENV];
|
|
726
|
+
const restoreHeadlessOnly = () => {
|
|
727
|
+
if (priorHeadlessOnly === undefined)
|
|
728
|
+
delete process.env[QA_RUN_HEADLESS_ONLY_ENV];
|
|
729
|
+
else
|
|
730
|
+
process.env[QA_RUN_HEADLESS_ONLY_ENV] = priorHeadlessOnly;
|
|
731
|
+
};
|
|
732
|
+
let provider;
|
|
733
|
+
if (runsVisual) {
|
|
734
|
+
if (!job.policy?.allow_metered_critique)
|
|
735
|
+
process.env[QA_RUN_HEADLESS_ONLY_ENV] = "1";
|
|
736
|
+
try {
|
|
737
|
+
provider =
|
|
738
|
+
options.critiqueProvider ??
|
|
739
|
+
(options.critiqueProviderLoader ? await options.critiqueProviderLoader() : undefined);
|
|
740
|
+
}
|
|
741
|
+
catch (err) {
|
|
742
|
+
log(`critique provider failed to load: ${err instanceof Error ? err.message : String(err)}`);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
const bandArgs = provider?.tileBudgetPx !== undefined
|
|
746
|
+
? ["--check-critique-band", String(Math.max(200, Math.min(1400, provider.tileBudgetPx)))]
|
|
747
|
+
: [];
|
|
748
|
+
const scopeArgs = visual === "full-page"
|
|
749
|
+
? []
|
|
750
|
+
: manifest.scopes.flatMap((s) => ["--review-pack-scope", s.selector]);
|
|
751
|
+
const gateCapturePlans = new Map();
|
|
710
752
|
const manifestGateArgs = manifest.checks.deterministic.flatMap((check) => MANIFEST_DETERMINISTIC_ARGS[check] ?? []);
|
|
711
753
|
const enforceConsole = manifest.checks.deterministic.includes("console");
|
|
712
754
|
const checks = job.checks ?? [];
|
|
@@ -734,6 +776,20 @@ export async function runQaMatrix(options) {
|
|
|
734
776
|
...(manifest.checks.visual !== "none" ? ["--no-screenshot"] : []),
|
|
735
777
|
...manifestGateArgs,
|
|
736
778
|
...applicable.flatMap((check) => check.args),
|
|
779
|
+
...(runsVisual
|
|
780
|
+
? [
|
|
781
|
+
"--review-pack-plan",
|
|
782
|
+
"--review-pack-context",
|
|
783
|
+
ctx.id,
|
|
784
|
+
"--qa-theme",
|
|
785
|
+
ctx.theme,
|
|
786
|
+
"--qa-state",
|
|
787
|
+
ctx.state,
|
|
788
|
+
...scopeArgs,
|
|
789
|
+
...bandArgs,
|
|
790
|
+
...critiqueMaxTilesArgs,
|
|
791
|
+
]
|
|
792
|
+
: []),
|
|
737
793
|
];
|
|
738
794
|
log(`gate ${ctx.id}: ${checkId}`);
|
|
739
795
|
const { res, wallTimeMs } = await timedExec(argv, baseEnv);
|
|
@@ -741,6 +797,25 @@ export async function runQaMatrix(options) {
|
|
|
741
797
|
const failures = [];
|
|
742
798
|
let outcome;
|
|
743
799
|
const envelope = existsSync(jsonPath) ? readEnvelope(jsonPath) : undefined;
|
|
800
|
+
if (runsVisual) {
|
|
801
|
+
try {
|
|
802
|
+
const capturePlan = validatePageReviewCapturePlan(envelope?.review_pack_capture_plan);
|
|
803
|
+
if (capturePlan.context_id !== ctx.id ||
|
|
804
|
+
capturePlan.viewport !== ctx.viewport ||
|
|
805
|
+
capturePlan.theme !== ctx.theme ||
|
|
806
|
+
capturePlan.state !== ctx.state) {
|
|
807
|
+
throw new Error("capture plan belongs to a different render context");
|
|
808
|
+
}
|
|
809
|
+
gateCapturePlans.set(ctx.id, capturePlan);
|
|
810
|
+
}
|
|
811
|
+
catch (err) {
|
|
812
|
+
blockers.push({
|
|
813
|
+
stage: "capture",
|
|
814
|
+
context_id: ctx.id,
|
|
815
|
+
reason: `capture plan unavailable: ${err instanceof Error ? err.message : String(err)}`,
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
}
|
|
744
819
|
const consoleFailures = enforceConsole ? parseConsoleFailures(envelope) : [];
|
|
745
820
|
if (!res.error && res.exitCode === 0 && existsSync(jsonPath)) {
|
|
746
821
|
if (consoleFailures.length > 0) {
|
|
@@ -864,8 +939,6 @@ export async function runQaMatrix(options) {
|
|
|
864
939
|
// Each context is rendered ONCE into the run's page review pack (full-page
|
|
865
940
|
// screenshot, tiles as PNG files, DOM, signature) through the same bounded
|
|
866
941
|
// pool the gates used, and its browser closes before any vision call.
|
|
867
|
-
const visual = manifest.checks.visual;
|
|
868
|
-
const cleanSoFar = blockers.length === 0 && commands.every((command) => command.outcome === "passed");
|
|
869
942
|
const packDir = join(outDir, PAGE_REVIEW_PACK_DIRNAME);
|
|
870
943
|
const capturedRecords = [];
|
|
871
944
|
const judgeCommand = options.reviewPackJudgeCommand?.(packDir);
|
|
@@ -928,61 +1001,49 @@ export async function runQaMatrix(options) {
|
|
|
928
1001
|
});
|
|
929
1002
|
}
|
|
930
1003
|
};
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
// for --check-critique) and the judge reuses the same instance.
|
|
934
|
-
const priorHeadlessOnly = process.env[QA_RUN_HEADLESS_ONLY_ENV];
|
|
935
|
-
const restoreHeadlessOnly = () => {
|
|
936
|
-
if (priorHeadlessOnly === undefined)
|
|
937
|
-
delete process.env[QA_RUN_HEADLESS_ONLY_ENV];
|
|
938
|
-
else
|
|
939
|
-
process.env[QA_RUN_HEADLESS_ONLY_ENV] = priorHeadlessOnly;
|
|
940
|
-
};
|
|
941
|
-
let provider;
|
|
942
|
-
const runsVisual = cleanSoFar && visual !== "none";
|
|
1004
|
+
enterStage("capture");
|
|
1005
|
+
const captureStart = Date.now();
|
|
943
1006
|
if (runsVisual) {
|
|
944
|
-
|
|
945
|
-
|
|
1007
|
+
writeFileSync(join(outDir, "preliminary-gates.json"), `${JSON.stringify(gateOutcomes, null, 2)}\n`);
|
|
1008
|
+
for (const gate of gateOutcomes)
|
|
1009
|
+
if (gate) {
|
|
1010
|
+
gate.outcome = "unknown";
|
|
1011
|
+
gate.failures = ["Authoritative same-visit gates and capture have not completed."];
|
|
1012
|
+
}
|
|
1013
|
+
const allocations = new Map();
|
|
946
1014
|
try {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
1015
|
+
const plans = contexts.map((ctx) => {
|
|
1016
|
+
const candidate = gateCapturePlans.get(ctx.id);
|
|
1017
|
+
if (!candidate)
|
|
1018
|
+
throw new Error(`no valid capture plan for ${ctx.id}; rerun after fixing its gate capture`);
|
|
1019
|
+
return candidate;
|
|
1020
|
+
});
|
|
1021
|
+
const ceilings = job.policy?.critique_max_tiles === undefined
|
|
1022
|
+
? undefined
|
|
1023
|
+
: Object.fromEntries(contexts.map((ctx) => [ctx.id, job.policy?.critique_max_tiles]));
|
|
1024
|
+
const allocation = allocateTileBudget(plans, job.policy?.critique_tile_budget ?? PAGE_REVIEW_DEFAULT_TILE_BUDGET, ceilings);
|
|
1025
|
+
for (const row of allocation.contexts)
|
|
1026
|
+
allocations.set(row.context_id, row);
|
|
1027
|
+
writeFileSync(join(outDir, "tile-allocation.json"), `${JSON.stringify(allocation, null, 2)}\n`);
|
|
1028
|
+
log(`tile budget: ${allocation.used}/${allocation.budget} allocated across ${allocations.size} contexts`);
|
|
950
1029
|
}
|
|
951
1030
|
catch (err) {
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
const bandArgs = provider?.tileBudgetPx !== undefined
|
|
957
|
-
? ["--check-critique-band", String(Math.max(200, Math.min(1400, provider.tileBudgetPx)))]
|
|
958
|
-
: [];
|
|
959
|
-
const scopeArgs = visual === "full-page"
|
|
960
|
-
? []
|
|
961
|
-
: manifest.scopes.flatMap((s) => ["--review-pack-scope", s.selector]);
|
|
962
|
-
// Gate-hit rectangles ride into each context's capture child so the bands
|
|
963
|
-
// they land in are cut even past the tile cap (`hit band N` tiles). The
|
|
964
|
-
// gates ran first, so the rects are known before the page is captured.
|
|
965
|
-
const hitRectsByContext = new Map();
|
|
966
|
-
for (const gate of gateRecords()) {
|
|
967
|
-
for (const hit of gate.hits ?? []) {
|
|
968
|
-
const list = hitRectsByContext.get(gate.context_id) ?? [];
|
|
969
|
-
if (list.length >= REVIEW_PACK_HIT_RECTS_PER_CONTEXT)
|
|
970
|
-
break;
|
|
971
|
-
const r = hit.rect;
|
|
972
|
-
list.push([r.x, r.y, Math.max(0, r.width), Math.max(0, r.height)].map((n) => Math.round(n)).join(","));
|
|
973
|
-
hitRectsByContext.set(gate.context_id, list);
|
|
1031
|
+
blockers.push({
|
|
1032
|
+
stage: "capture",
|
|
1033
|
+
reason: `tile allocation failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1034
|
+
});
|
|
974
1035
|
}
|
|
975
|
-
}
|
|
976
|
-
const hitRectArgs = (contextId) => (hitRectsByContext.get(contextId) ?? []).flatMap((spec) => ["--review-pack-hit-rect", spec]);
|
|
977
|
-
enterStage("capture");
|
|
978
|
-
const captureStart = Date.now();
|
|
979
|
-
if (runsVisual) {
|
|
980
1036
|
const captureOutcomes = new Array(contexts.length);
|
|
981
1037
|
const captureRecords = new Array(contexts.length);
|
|
982
1038
|
await runPool(contexts, concurrency, async (ctx, index) => {
|
|
983
1039
|
if (pastDeadline())
|
|
984
1040
|
return;
|
|
1041
|
+
const allocation = allocations.get(ctx.id);
|
|
1042
|
+
if (!allocation)
|
|
1043
|
+
return;
|
|
985
1044
|
const outPrefix = join(outDir, `${ctx.id}-capture`);
|
|
1045
|
+
const allocationFile = `${outPrefix}-allocation.json`;
|
|
1046
|
+
writeFileSync(allocationFile, `${JSON.stringify(allocation)}\n`);
|
|
986
1047
|
const argv = [
|
|
987
1048
|
...browseArgv,
|
|
988
1049
|
job.target,
|
|
@@ -998,11 +1059,16 @@ export async function runQaMatrix(options) {
|
|
|
998
1059
|
ctx.theme,
|
|
999
1060
|
"--qa-state",
|
|
1000
1061
|
ctx.state,
|
|
1001
|
-
|
|
1062
|
+
"--review-pack-reservation",
|
|
1063
|
+
allocationFile,
|
|
1064
|
+
"--review-pack-plan",
|
|
1065
|
+
...manifestGateArgs,
|
|
1066
|
+
...checks
|
|
1067
|
+
.filter((check) => check.contexts === undefined || check.contexts.includes(ctx.id))
|
|
1068
|
+
.flatMap((check) => check.args),
|
|
1002
1069
|
...scopeArgs,
|
|
1003
1070
|
...critiqueMaxTilesArgs,
|
|
1004
1071
|
...bandArgs,
|
|
1005
|
-
...hitRectArgs(ctx.id),
|
|
1006
1072
|
];
|
|
1007
1073
|
log(`capture ${ctx.id}${scopeArgs.length > 0 ? ` [${manifest.scopes.map((s) => s.selector).join(",")}]` : ""}`);
|
|
1008
1074
|
const { res, wallTimeMs } = await timedExec(argv, baseEnv);
|
|
@@ -1012,16 +1078,48 @@ export async function runQaMatrix(options) {
|
|
|
1012
1078
|
const failures = [];
|
|
1013
1079
|
let outcome;
|
|
1014
1080
|
let record;
|
|
1015
|
-
if (!res.error &&
|
|
1081
|
+
if (!res.error &&
|
|
1082
|
+
(res.exitCode === 0 || res.exitCode === 2) &&
|
|
1083
|
+
envelope &&
|
|
1084
|
+
report?.context_id) {
|
|
1016
1085
|
try {
|
|
1017
1086
|
record = readPackContext(packDir, report.context_id);
|
|
1018
|
-
|
|
1087
|
+
const currentPlan = validatePageReviewCapturePlan(envelope.review_pack_capture_plan);
|
|
1088
|
+
const transaction = envelope.review_pack_transaction;
|
|
1089
|
+
if (!record.capture_plan ||
|
|
1090
|
+
record.id !== ctx.id ||
|
|
1091
|
+
capturePlanDigest(record.capture_plan) !== capturePlanDigest(currentPlan) ||
|
|
1092
|
+
transaction?.source_digest !== currentPlan.source_digest ||
|
|
1093
|
+
transaction.attempts?.at(-1)?.status !== "captured" ||
|
|
1094
|
+
record.tiles.length > allocation.selected_ids.length) {
|
|
1095
|
+
throw new Error("Fresh gates, source identity and native capture are not bound to the same transaction.");
|
|
1096
|
+
}
|
|
1097
|
+
const freshFailures = [
|
|
1098
|
+
...parseGateFailures(envelope),
|
|
1099
|
+
...(enforceConsole ? parseConsoleFailures(envelope) : []),
|
|
1100
|
+
];
|
|
1101
|
+
if (res.exitCode === 2 && !freshFailures.length)
|
|
1102
|
+
freshFailures.push("Fresh gate command returned exit code 2.");
|
|
1103
|
+
const preliminaryGate = gateOutcomes[index];
|
|
1104
|
+
if (!preliminaryGate)
|
|
1105
|
+
throw new Error("Missing context gate identity.");
|
|
1106
|
+
Object.assign(preliminaryGate, {
|
|
1107
|
+
argv,
|
|
1108
|
+
exit_code: res.exitCode,
|
|
1109
|
+
outcome: freshFailures.length ? "failed" : "passed",
|
|
1110
|
+
failures: freshFailures,
|
|
1111
|
+
artifacts: gatherArtifacts(outPrefix),
|
|
1112
|
+
wall_time_ms: wallTimeMs,
|
|
1113
|
+
});
|
|
1114
|
+
outcome = freshFailures.length ? "failed" : "passed";
|
|
1115
|
+
failures.push(...freshFailures);
|
|
1019
1116
|
}
|
|
1020
1117
|
catch (err) {
|
|
1021
1118
|
outcome = "unknown";
|
|
1022
1119
|
const reason = `pack context unreadable: ${err instanceof Error ? err.message : String(err)}`;
|
|
1023
1120
|
failures.push(reason);
|
|
1024
1121
|
blockers.push({ stage: "capture", context_id: ctx.id, reason });
|
|
1122
|
+
record = undefined;
|
|
1025
1123
|
}
|
|
1026
1124
|
}
|
|
1027
1125
|
else {
|
|
@@ -1099,7 +1197,50 @@ export async function runQaMatrix(options) {
|
|
|
1099
1197
|
};
|
|
1100
1198
|
for (const row of judged.contexts) {
|
|
1101
1199
|
judgedById.set(row.context_id, row);
|
|
1200
|
+
const captured = capturedRecords.find((record) => record.id === row.context_id);
|
|
1201
|
+
if (captured)
|
|
1202
|
+
captured.evidence_context = row.record.evidence_context;
|
|
1102
1203
|
let contextOutcome = row.outcome === "pass" ? "passed" : row.outcome === "fail" ? "failed" : "unknown";
|
|
1204
|
+
let dismissed = [];
|
|
1205
|
+
if (job.policy?.accept_dispositions === true &&
|
|
1206
|
+
(row.outcome === "pass" || row.outcome === "fail") &&
|
|
1207
|
+
row.tiles_unjudged === 0 &&
|
|
1208
|
+
!row.record.capture_incomplete &&
|
|
1209
|
+
!row.coverage.capped) {
|
|
1210
|
+
try {
|
|
1211
|
+
const evidence = buildPackNativeEvidence(row.record, readPackTiles(packDir, row.record), DEFAULT_CRITIQUE_RUBRIC);
|
|
1212
|
+
const slot = loadReviewDecisions(job.target, { viewport: row.record.viewport, theme: row.record.theme, state: row.record.state }, options.snapshotStore ?? {});
|
|
1213
|
+
const reviewed = applyPackReviewDecisions({
|
|
1214
|
+
target: job.target,
|
|
1215
|
+
evidence,
|
|
1216
|
+
findings: row.findings,
|
|
1217
|
+
slot,
|
|
1218
|
+
enabled: true,
|
|
1219
|
+
});
|
|
1220
|
+
dismissed = reviewed.applied;
|
|
1221
|
+
if (dismissed.length > 0 &&
|
|
1222
|
+
reviewed.findings.every((finding) => finding.severity !== "high")) {
|
|
1223
|
+
contextOutcome = "passed";
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
catch (err) {
|
|
1227
|
+
contextOutcome = "unknown";
|
|
1228
|
+
blockers.push({
|
|
1229
|
+
stage: "critique",
|
|
1230
|
+
context_id: row.context_id,
|
|
1231
|
+
reason: `reviewed disposition evidence unavailable: ${err instanceof Error ? err.message : String(err)}`,
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
if (row.record.capture_incomplete) {
|
|
1236
|
+
if (contextOutcome !== "failed")
|
|
1237
|
+
contextOutcome = "unknown";
|
|
1238
|
+
blockers.push({
|
|
1239
|
+
stage: "capture",
|
|
1240
|
+
context_id: row.context_id,
|
|
1241
|
+
reason: "native capture evidence is incomplete; recapture this context before signoff",
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1103
1244
|
if (row.outcome === "skipped") {
|
|
1104
1245
|
const detail = row.error ?? "critique reported no conclusive outcome";
|
|
1105
1246
|
blockers.push({
|
|
@@ -1116,13 +1257,13 @@ export async function runQaMatrix(options) {
|
|
|
1116
1257
|
blockers.push({
|
|
1117
1258
|
stage: "critique",
|
|
1118
1259
|
context_id: row.context_id,
|
|
1119
|
-
reason:
|
|
1120
|
-
|
|
1260
|
+
reason: row.error ??
|
|
1261
|
+
`judge did not review ${row.tiles_unjudged} of ${row.tiles_total} tile(s) before the ` +
|
|
1262
|
+
"run deadline; nothing is proven for them",
|
|
1121
1263
|
});
|
|
1122
1264
|
}
|
|
1123
|
-
//
|
|
1124
|
-
//
|
|
1125
|
-
// `coverage` and leaves the verdict to the tiles that were seen.
|
|
1265
|
+
// Selected bands may leave gaps anywhere. Signoff needs complete
|
|
1266
|
+
// coverage, while review mode reports what was actually captured.
|
|
1126
1267
|
if (job.mode === "signoff" && row.coverage.capped && contextOutcome !== "failed") {
|
|
1127
1268
|
contextOutcome = "unknown";
|
|
1128
1269
|
blockers.push({
|
|
@@ -1130,7 +1271,7 @@ export async function runQaMatrix(options) {
|
|
|
1130
1271
|
context_id: row.context_id,
|
|
1131
1272
|
reason: `critique coverage capped: ${row.coverage.bands_reviewed} of ${row.coverage.bands_total} bands ` +
|
|
1132
1273
|
`reviewed (${row.coverage.reviewed_height_px} of ${row.coverage.page_height_px} px); raise ` +
|
|
1133
|
-
"policy.
|
|
1274
|
+
"policy.critique_tile_budget (and any explicit per-context ceiling) for full signoff coverage",
|
|
1134
1275
|
});
|
|
1135
1276
|
}
|
|
1136
1277
|
const scopeById = new Map(row.record.tiles.map((tile) => [tile.id, tile.scope]));
|
|
@@ -1141,6 +1282,7 @@ export async function runQaMatrix(options) {
|
|
|
1141
1282
|
tiles_reviewed: row.tiles_reviewed,
|
|
1142
1283
|
tiles_reused: row.tiles_reused,
|
|
1143
1284
|
outcome: contextOutcome,
|
|
1285
|
+
...(dismissed.length > 0 ? { dismissed } : {}),
|
|
1144
1286
|
findings: row.findings.map((finding) => {
|
|
1145
1287
|
const selector = scopeById.get(finding.tile_id);
|
|
1146
1288
|
return {
|
|
@@ -1163,7 +1305,7 @@ export async function runQaMatrix(options) {
|
|
|
1163
1305
|
// -------------------------------------------------------------- snapshot
|
|
1164
1306
|
// Signoff persists each context's baseline from the pack's own files (no
|
|
1165
1307
|
// browser). The critique rides along only when the whole tile set was
|
|
1166
|
-
//
|
|
1308
|
+
// judged or safely reused, uncapped, and unscoped — a partial or scoped review must
|
|
1167
1309
|
// never become the next baseline's finding record. When the manifest
|
|
1168
1310
|
// required no visual pass, a dedicated browse --qa-snapshot pass still runs.
|
|
1169
1311
|
enterStage("snapshot");
|
|
@@ -1176,14 +1318,14 @@ export async function runQaMatrix(options) {
|
|
|
1176
1318
|
const row = judgedById.get(record.id);
|
|
1177
1319
|
const persistCritique = row !== undefined &&
|
|
1178
1320
|
(row.outcome === "pass" || row.outcome === "fail") &&
|
|
1321
|
+
!record.capture_incomplete &&
|
|
1179
1322
|
!record.coverage.capped &&
|
|
1180
|
-
row.tiles_reused === 0 &&
|
|
1181
1323
|
row.tiles_unjudged === 0 &&
|
|
1182
1324
|
record.scopes.length === 0;
|
|
1183
1325
|
const persisted = persistCritique && row
|
|
1184
1326
|
? {
|
|
1185
|
-
contract_version:
|
|
1186
|
-
rubric_digest:
|
|
1327
|
+
contract_version: 2,
|
|
1328
|
+
rubric_digest: "",
|
|
1187
1329
|
outcome: row.outcome,
|
|
1188
1330
|
findings: row.findings.map(({ tile_id: _tileId, ...finding }) => finding),
|
|
1189
1331
|
tiles: record.tiles.map((tile) => ({
|
|
@@ -1197,10 +1339,15 @@ export async function runQaMatrix(options) {
|
|
|
1197
1339
|
}
|
|
1198
1340
|
: undefined;
|
|
1199
1341
|
try {
|
|
1342
|
+
const tileEvidence = buildPackNativeEvidence(record, readPackTiles(packDir, record), DEFAULT_CRITIQUE_RUBRIC);
|
|
1343
|
+
if (persisted) {
|
|
1344
|
+
persisted.contract_version = tileEvidence.context.critique_contract_version;
|
|
1345
|
+
persisted.rubric_digest = tileEvidence.context.rubric_digest;
|
|
1346
|
+
}
|
|
1200
1347
|
const saved = saveQaSnapshot(job.target, { viewport: record.viewport, theme: record.theme, state: record.state }, {
|
|
1201
1348
|
signature: readPackSignature(packDir, record),
|
|
1202
1349
|
domHtml: readPackDom(packDir, record),
|
|
1203
|
-
|
|
1350
|
+
tileEvidence,
|
|
1204
1351
|
...(persisted ? { critique: persisted } : {}),
|
|
1205
1352
|
}, options.snapshotStore ?? {});
|
|
1206
1353
|
savedSnapshots.set(record.id, saved.path);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type PageReviewDecisionSlot, type PageReviewNativeEvidence } from "./page-review-contracts.js";
|
|
1
2
|
import { type QaContext, type QaSignature } from "./qa-plan.js";
|
|
2
3
|
import type { PersistedCritique } from "./qa-reuse.js";
|
|
3
4
|
declare const SNAPSHOT_DIR: string;
|
|
@@ -14,10 +15,14 @@ export interface StoredQaSnapshot {
|
|
|
14
15
|
/** Critique results persisted with the snapshot (full-coverage runs only) —
|
|
15
16
|
* what the band-diff reuse layer replays for provably-unchanged regions. */
|
|
16
17
|
critique?: PersistedCritique;
|
|
18
|
+
tileEvidence?: PageReviewNativeEvidence;
|
|
17
19
|
}
|
|
18
20
|
/** Filesystem-safe key for a target URL/file + render context. The digest
|
|
19
21
|
* disambiguates targets whose sanitized slugs collide. */
|
|
20
22
|
export declare function qaSnapshotKey(target: string): string;
|
|
23
|
+
export declare function loadReviewDecisions(target: string, context: QaContext, opts?: QaSnapshotStoreOptions): PageReviewDecisionSlot | null;
|
|
24
|
+
/** Decisions contain text and digests only; replacing a baseline cannot touch this slot. */
|
|
25
|
+
export declare function saveReviewDecisions(target: string, context: QaContext, slot: PageReviewDecisionSlot, opts?: QaSnapshotStoreOptions): void;
|
|
21
26
|
/**
|
|
22
27
|
* Persist a QA snapshot atomically. The whole context directory is staged as
|
|
23
28
|
* `<dir>.tmp-<pid>` and renamed into place, replacing any prior snapshot for
|
|
@@ -28,6 +33,7 @@ export declare function saveQaSnapshot(target: string, context: QaContext, conte
|
|
|
28
33
|
domHtml?: string;
|
|
29
34
|
screenshotPng?: Buffer;
|
|
30
35
|
critique?: PersistedCritique;
|
|
36
|
+
tileEvidence?: PageReviewNativeEvidence;
|
|
31
37
|
}, opts?: QaSnapshotStoreOptions): StoredQaSnapshot;
|
|
32
38
|
/** Load the persisted snapshot for a target + context, or null. A corrupt
|
|
33
39
|
* signature file returns null (and the caller re-acquires a baseline) rather
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qa-snapshot.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-snapshot.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"qa-snapshot.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-snapshot.ts"],"names":[],"mappings":"AA2BA,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC9B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,QAAA,MAAM,YAAY,QAA0D,CAAC;AAE7E,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,WAAW,CAAC;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;gFAC4E;IAC5E,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,YAAY,CAAC,EAAE,wBAAwB,CAAC;CACzC;AAED;0DAC0D;AAC1D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiBpD;AA2HD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,IAAI,GAAE,sBAA2B,GAChC,sBAAsB,GAAG,IAAI,CAc/B;AAED,4FAA4F;AAC5F,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,IAAI,EAAE,sBAAsB,EAC5B,IAAI,GAAE,sBAA2B,GAChC,IAAI,CAaN;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE;IACP,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,YAAY,CAAC,EAAE,wBAAwB,CAAC;CACzC,EACD,IAAI,GAAE,sBAA2B,GAChC,gBAAgB,CAoElB;AAED;;4DAE4D;AAC5D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,IAAI,GAAE,sBAA2B,GAChC,gBAAgB,GAAG,IAAI,CAqEzB;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,sBAA2B,GAAG,MAAM,EAAE,CAUjF;AAED,MAAM,WAAW,kBAAkB;IACjC;;uCAEmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACrD,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;CAC/E,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwB9B;AAED,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,CAAC"}
|