codex-orchestrator 0.1.51 → 2.0.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/CHANGELOG.md +21 -0
- package/README.md +45 -389
- package/dist/src/index.d.ts +16 -46
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -24
- package/dist/src/index.js.map +1 -1
- package/dist/src/v2/acceptance-proof.d.ts +111 -0
- package/dist/src/v2/acceptance-proof.d.ts.map +1 -0
- package/dist/src/v2/acceptance-proof.js +427 -0
- package/dist/src/v2/acceptance-proof.js.map +1 -0
- package/dist/src/v2/adapters/command.d.ts.map +1 -0
- package/dist/src/v2/adapters/command.js.map +1 -0
- package/dist/src/v2/adapters/durable-atomic-file.d.ts.map +1 -0
- package/dist/src/v2/adapters/durable-atomic-file.js.map +1 -0
- package/dist/src/v2/adapters/gh-cli.d.ts.map +1 -0
- package/dist/src/v2/adapters/gh-cli.js.map +1 -0
- package/dist/src/v2/adapters/gh-issue-adapter.d.ts.map +1 -0
- package/dist/src/v2/adapters/gh-issue-adapter.js.map +1 -0
- package/dist/src/v2/adapters/gh-pull-request-adapter.d.ts.map +1 -0
- package/dist/src/v2/adapters/gh-pull-request-adapter.js.map +1 -0
- package/dist/src/v2/adapters/issues.d.ts.map +1 -0
- package/dist/src/v2/adapters/issues.js.map +1 -0
- package/dist/src/v2/adapters/mission-coordinator-lock.d.ts.map +1 -0
- package/dist/src/v2/adapters/mission-coordinator-lock.js.map +1 -0
- package/dist/src/v2/adapters/path-policy.d.ts.map +1 -0
- package/dist/src/v2/adapters/path-policy.js.map +1 -0
- package/dist/src/v2/adapters/pull-requests.d.ts.map +1 -0
- package/dist/src/v2/adapters/pull-requests.js.map +1 -0
- package/dist/src/v2/adapters/target-activity-fence.d.ts.map +1 -0
- package/dist/src/{runner → v2/adapters}/target-activity-fence.js +1 -1
- package/dist/src/v2/adapters/target-activity-fence.js.map +1 -0
- package/dist/src/{git → v2/adapters}/worktree.d.ts +1 -1
- package/dist/src/v2/adapters/worktree.d.ts.map +1 -0
- package/dist/src/{git → v2/adapters}/worktree.js +2 -2
- package/dist/src/v2/adapters/worktree.js.map +1 -0
- package/dist/src/v2/atomic-store.d.ts +36 -0
- package/dist/src/v2/atomic-store.d.ts.map +1 -0
- package/dist/src/v2/atomic-store.js +328 -0
- package/dist/src/v2/atomic-store.js.map +1 -0
- package/dist/src/v2/candidate-cli.d.ts +22 -0
- package/dist/src/v2/candidate-cli.d.ts.map +1 -0
- package/dist/src/v2/candidate-cli.js +161 -0
- package/dist/src/v2/candidate-cli.js.map +1 -0
- package/dist/src/v2/checked-change.d.ts +49 -0
- package/dist/src/v2/checked-change.d.ts.map +1 -0
- package/dist/src/v2/checked-change.js +139 -0
- package/dist/src/v2/checked-change.js.map +1 -0
- package/dist/src/v2/cli-contract.d.ts +8 -0
- package/dist/src/v2/cli-contract.d.ts.map +1 -0
- package/dist/src/v2/cli-contract.js +32 -0
- package/dist/src/v2/cli-contract.js.map +1 -0
- package/dist/src/v2/codex-process.d.ts +71 -0
- package/dist/src/v2/codex-process.d.ts.map +1 -0
- package/dist/src/v2/codex-process.js +404 -0
- package/dist/src/v2/codex-process.js.map +1 -0
- package/dist/src/v2/config.d.ts +45 -0
- package/dist/src/v2/config.d.ts.map +1 -0
- package/dist/src/v2/config.js +139 -0
- package/dist/src/v2/config.js.map +1 -0
- package/dist/src/v2/containment.d.ts +55 -0
- package/dist/src/v2/containment.d.ts.map +1 -0
- package/dist/src/v2/containment.js +370 -0
- package/dist/src/v2/containment.js.map +1 -0
- package/dist/src/v2/implementation-report.d.ts +18 -0
- package/dist/src/v2/implementation-report.d.ts.map +1 -0
- package/dist/src/v2/implementation-report.js +147 -0
- package/dist/src/v2/implementation-report.js.map +1 -0
- package/dist/src/v2/legacy-cutover.d.ts +52 -0
- package/dist/src/v2/legacy-cutover.d.ts.map +1 -0
- package/dist/src/v2/legacy-cutover.js +87 -0
- package/dist/src/v2/legacy-cutover.js.map +1 -0
- package/dist/src/v2/mobile-lease.d.ts +97 -0
- package/dist/src/v2/mobile-lease.d.ts.map +1 -0
- package/dist/src/v2/mobile-lease.js +253 -0
- package/dist/src/v2/mobile-lease.js.map +1 -0
- package/dist/src/v2/proof-report.d.ts +118 -0
- package/dist/src/v2/proof-report.d.ts.map +1 -0
- package/dist/src/v2/proof-report.js +703 -0
- package/dist/src/v2/proof-report.js.map +1 -0
- package/dist/src/v2/proof-store.d.ts +42 -0
- package/dist/src/v2/proof-store.d.ts.map +1 -0
- package/dist/src/v2/proof-store.js +180 -0
- package/dist/src/v2/proof-store.js.map +1 -0
- package/dist/src/v2/report-envelope.d.ts +4 -0
- package/dist/src/v2/report-envelope.d.ts.map +1 -0
- package/dist/src/v2/report-envelope.js +46 -0
- package/dist/src/v2/report-envelope.js.map +1 -0
- package/dist/src/v2/run-issue.d.ts +213 -0
- package/dist/src/v2/run-issue.d.ts.map +1 -0
- package/dist/src/v2/run-issue.js +906 -0
- package/dist/src/v2/run-issue.js.map +1 -0
- package/dist/src/v2/run-store.d.ts +136 -0
- package/dist/src/v2/run-store.d.ts.map +1 -0
- package/dist/src/v2/run-store.js +346 -0
- package/dist/src/v2/run-store.js.map +1 -0
- package/dist/src/v2/runtime-assets.d.ts +31 -0
- package/dist/src/v2/runtime-assets.d.ts.map +1 -0
- package/dist/src/v2/runtime-assets.js +473 -0
- package/dist/src/v2/runtime-assets.js.map +1 -0
- package/dist/src/v2/runtime.d.ts +137 -0
- package/dist/src/v2/runtime.d.ts.map +1 -0
- package/dist/src/v2/runtime.js +847 -0
- package/dist/src/v2/runtime.js.map +1 -0
- package/dist/src/v2/setup-cli.d.ts +5 -0
- package/dist/src/v2/setup-cli.d.ts.map +1 -0
- package/dist/src/v2/setup-cli.js +83 -0
- package/dist/src/v2/setup-cli.js.map +1 -0
- package/dist/src/v2/setup-runtime.d.ts +6 -0
- package/dist/src/v2/setup-runtime.d.ts.map +1 -0
- package/dist/src/v2/setup-runtime.js +213 -0
- package/dist/src/v2/setup-runtime.js.map +1 -0
- package/dist/src/v2/setup-store.d.ts +19 -0
- package/dist/src/v2/setup-store.d.ts.map +1 -0
- package/dist/src/v2/setup-store.js +208 -0
- package/dist/src/v2/setup-store.js.map +1 -0
- package/dist/src/v2/setup.d.ts +147 -0
- package/dist/src/v2/setup.d.ts.map +1 -0
- package/dist/src/v2/setup.js +529 -0
- package/dist/src/v2/setup.js.map +1 -0
- package/docs/deep-dive.md +54 -803
- package/internal-skills/acceptance-proof/SKILL.md +14 -0
- package/internal-skills/acceptance-proof/references/android.md +14 -0
- package/internal-skills/acceptance-proof/references/browser.md +13 -0
- package/internal-skills/acceptance-proof/references/ios.md +14 -0
- package/internal-skills/acceptance-proof/tools/android-lease.mjs +280 -0
- package/internal-skills/acceptance-proof/tools/ios-lease.mjs +288 -0
- package/internal-skills/agent-auto/SKILL.md +14 -0
- package/package.json +11 -18
- package/bridge-runtime.json +0 -2719
- package/dist/src/bridge-runtime.d.ts +0 -17
- package/dist/src/bridge-runtime.d.ts.map +0 -1
- package/dist/src/bridge-runtime.js +0 -170
- package/dist/src/bridge-runtime.js.map +0 -1
- package/dist/src/cli.d.ts +0 -3
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js +0 -569
- package/dist/src/cli.js.map +0 -1
- package/dist/src/codex/command-adapter.d.ts +0 -47
- package/dist/src/codex/command-adapter.d.ts.map +0 -1
- package/dist/src/codex/command-adapter.js +0 -169
- package/dist/src/codex/command-adapter.js.map +0 -1
- package/dist/src/codex/mobile-device-guard.d.ts +0 -7
- package/dist/src/codex/mobile-device-guard.d.ts.map +0 -1
- package/dist/src/codex/mobile-device-guard.js +0 -63
- package/dist/src/codex/mobile-device-guard.js.map +0 -1
- package/dist/src/config/constants.d.ts +0 -6
- package/dist/src/config/constants.d.ts.map +0 -1
- package/dist/src/config/constants.js +0 -19
- package/dist/src/config/constants.js.map +0 -1
- package/dist/src/config/schema.d.ts +0 -234
- package/dist/src/config/schema.d.ts.map +0 -1
- package/dist/src/config/schema.js +0 -673
- package/dist/src/config/schema.js.map +0 -1
- package/dist/src/fs/durable-atomic-file.d.ts.map +0 -1
- package/dist/src/fs/durable-atomic-file.js.map +0 -1
- package/dist/src/git/base-branch.d.ts +0 -26
- package/dist/src/git/base-branch.d.ts.map +0 -1
- package/dist/src/git/base-branch.js +0 -45
- package/dist/src/git/base-branch.js.map +0 -1
- package/dist/src/git/worktree.d.ts.map +0 -1
- package/dist/src/git/worktree.js.map +0 -1
- package/dist/src/github/gh-cli.d.ts.map +0 -1
- package/dist/src/github/gh-cli.js.map +0 -1
- package/dist/src/github/gh-issue-adapter.d.ts.map +0 -1
- package/dist/src/github/gh-issue-adapter.js.map +0 -1
- package/dist/src/github/gh-pull-request-adapter.d.ts.map +0 -1
- package/dist/src/github/gh-pull-request-adapter.js.map +0 -1
- package/dist/src/github/issues.d.ts.map +0 -1
- package/dist/src/github/issues.js.map +0 -1
- package/dist/src/github/pull-requests.d.ts.map +0 -1
- package/dist/src/github/pull-requests.js.map +0 -1
- package/dist/src/package-info.d.ts +0 -6
- package/dist/src/package-info.d.ts.map +0 -1
- package/dist/src/package-info.js +0 -13
- package/dist/src/package-info.js.map +0 -1
- package/dist/src/path-policy.d.ts.map +0 -1
- package/dist/src/path-policy.js.map +0 -1
- package/dist/src/process/command.d.ts.map +0 -1
- package/dist/src/process/command.js.map +0 -1
- package/dist/src/review-handoff.d.ts +0 -3
- package/dist/src/review-handoff.d.ts.map +0 -1
- package/dist/src/review-handoff.js +0 -8
- package/dist/src/review-handoff.js.map +0 -1
- package/dist/src/runner/acceptance-proof-loop.d.ts +0 -97
- package/dist/src/runner/acceptance-proof-loop.d.ts.map +0 -1
- package/dist/src/runner/acceptance-proof-loop.js +0 -404
- package/dist/src/runner/acceptance-proof-loop.js.map +0 -1
- package/dist/src/runner/acceptance-proof-runner.d.ts +0 -24
- package/dist/src/runner/acceptance-proof-runner.d.ts.map +0 -1
- package/dist/src/runner/acceptance-proof-runner.js +0 -121
- package/dist/src/runner/acceptance-proof-runner.js.map +0 -1
- package/dist/src/runner/acceptance-proof.d.ts +0 -189
- package/dist/src/runner/acceptance-proof.d.ts.map +0 -1
- package/dist/src/runner/acceptance-proof.js +0 -594
- package/dist/src/runner/acceptance-proof.js.map +0 -1
- package/dist/src/runner/agent-attempt.d.ts +0 -105
- package/dist/src/runner/agent-attempt.d.ts.map +0 -1
- package/dist/src/runner/agent-attempt.js +0 -245
- package/dist/src/runner/agent-attempt.js.map +0 -1
- package/dist/src/runner/android-visual-proof-command.d.ts +0 -26
- package/dist/src/runner/android-visual-proof-command.d.ts.map +0 -1
- package/dist/src/runner/android-visual-proof-command.js +0 -592
- package/dist/src/runner/android-visual-proof-command.js.map +0 -1
- package/dist/src/runner/auto-visual-proof-command.d.ts +0 -15
- package/dist/src/runner/auto-visual-proof-command.d.ts.map +0 -1
- package/dist/src/runner/auto-visual-proof-command.js +0 -64
- package/dist/src/runner/auto-visual-proof-command.js.map +0 -1
- package/dist/src/runner/browser-proof-contract.d.ts +0 -134
- package/dist/src/runner/browser-proof-contract.d.ts.map +0 -1
- package/dist/src/runner/browser-proof-contract.js +0 -400
- package/dist/src/runner/browser-proof-contract.js.map +0 -1
- package/dist/src/runner/browser-visual-proof-command.d.ts +0 -101
- package/dist/src/runner/browser-visual-proof-command.d.ts.map +0 -1
- package/dist/src/runner/browser-visual-proof-command.js +0 -532
- package/dist/src/runner/browser-visual-proof-command.js.map +0 -1
- package/dist/src/runner/command-utils.d.ts +0 -15
- package/dist/src/runner/command-utils.d.ts.map +0 -1
- package/dist/src/runner/command-utils.js +0 -228
- package/dist/src/runner/command-utils.js.map +0 -1
- package/dist/src/runner/completion-report.d.ts +0 -121
- package/dist/src/runner/completion-report.d.ts.map +0 -1
- package/dist/src/runner/completion-report.js +0 -381
- package/dist/src/runner/completion-report.js.map +0 -1
- package/dist/src/runner/context-snapshot.d.ts +0 -33
- package/dist/src/runner/context-snapshot.d.ts.map +0 -1
- package/dist/src/runner/context-snapshot.js +0 -99
- package/dist/src/runner/context-snapshot.js.map +0 -1
- package/dist/src/runner/daemon-command.d.ts +0 -30
- package/dist/src/runner/daemon-command.d.ts.map +0 -1
- package/dist/src/runner/daemon-command.js +0 -262
- package/dist/src/runner/daemon-command.js.map +0 -1
- package/dist/src/runner/doctor-command.d.ts +0 -41
- package/dist/src/runner/doctor-command.d.ts.map +0 -1
- package/dist/src/runner/doctor-command.js +0 -177
- package/dist/src/runner/doctor-command.js.map +0 -1
- package/dist/src/runner/durable-run-summary.d.ts +0 -80
- package/dist/src/runner/durable-run-summary.d.ts.map +0 -1
- package/dist/src/runner/durable-run-summary.js +0 -200
- package/dist/src/runner/durable-run-summary.js.map +0 -1
- package/dist/src/runner/flutter-sdk-discovery.d.ts +0 -5
- package/dist/src/runner/flutter-sdk-discovery.d.ts.map +0 -1
- package/dist/src/runner/flutter-sdk-discovery.js +0 -103
- package/dist/src/runner/flutter-sdk-discovery.js.map +0 -1
- package/dist/src/runner/fresh-context-review.d.ts +0 -22
- package/dist/src/runner/fresh-context-review.d.ts.map +0 -1
- package/dist/src/runner/fresh-context-review.js +0 -177
- package/dist/src/runner/fresh-context-review.js.map +0 -1
- package/dist/src/runner/handoff-evidence.d.ts +0 -141
- package/dist/src/runner/handoff-evidence.d.ts.map +0 -1
- package/dist/src/runner/handoff-evidence.js +0 -543
- package/dist/src/runner/handoff-evidence.js.map +0 -1
- package/dist/src/runner/hygiene-cleanup.d.ts +0 -15
- package/dist/src/runner/hygiene-cleanup.d.ts.map +0 -1
- package/dist/src/runner/hygiene-cleanup.js +0 -25
- package/dist/src/runner/hygiene-cleanup.js.map +0 -1
- package/dist/src/runner/ios-visual-proof-command.d.ts +0 -25
- package/dist/src/runner/ios-visual-proof-command.d.ts.map +0 -1
- package/dist/src/runner/ios-visual-proof-command.js +0 -353
- package/dist/src/runner/ios-visual-proof-command.js.map +0 -1
- package/dist/src/runner/issue-state-machine.d.ts +0 -39
- package/dist/src/runner/issue-state-machine.d.ts.map +0 -1
- package/dist/src/runner/issue-state-machine.js +0 -124
- package/dist/src/runner/issue-state-machine.js.map +0 -1
- package/dist/src/runner/issue-tree.d.ts +0 -65
- package/dist/src/runner/issue-tree.d.ts.map +0 -1
- package/dist/src/runner/issue-tree.js +0 -474
- package/dist/src/runner/issue-tree.js.map +0 -1
- package/dist/src/runner/lifecycle-events.d.ts +0 -44
- package/dist/src/runner/lifecycle-events.d.ts.map +0 -1
- package/dist/src/runner/lifecycle-events.js +0 -108
- package/dist/src/runner/lifecycle-events.js.map +0 -1
- package/dist/src/runner/local-execution-session.d.ts +0 -112
- package/dist/src/runner/local-execution-session.d.ts.map +0 -1
- package/dist/src/runner/local-execution-session.js +0 -1064
- package/dist/src/runner/local-execution-session.js.map +0 -1
- package/dist/src/runner/local-state.d.ts +0 -44
- package/dist/src/runner/local-state.d.ts.map +0 -1
- package/dist/src/runner/local-state.js +0 -150
- package/dist/src/runner/local-state.js.map +0 -1
- package/dist/src/runner/mission-activation.d.ts +0 -29
- package/dist/src/runner/mission-activation.d.ts.map +0 -1
- package/dist/src/runner/mission-activation.js +0 -54
- package/dist/src/runner/mission-activation.js.map +0 -1
- package/dist/src/runner/mission-agent-broker.d.ts +0 -53
- package/dist/src/runner/mission-agent-broker.d.ts.map +0 -1
- package/dist/src/runner/mission-agent-broker.js +0 -182
- package/dist/src/runner/mission-agent-broker.js.map +0 -1
- package/dist/src/runner/mission-cancellation.d.ts +0 -77
- package/dist/src/runner/mission-cancellation.d.ts.map +0 -1
- package/dist/src/runner/mission-cancellation.js +0 -180
- package/dist/src/runner/mission-cancellation.js.map +0 -1
- package/dist/src/runner/mission-canonical-path.d.ts +0 -34
- package/dist/src/runner/mission-canonical-path.d.ts.map +0 -1
- package/dist/src/runner/mission-canonical-path.js +0 -121
- package/dist/src/runner/mission-canonical-path.js.map +0 -1
- package/dist/src/runner/mission-capability-kernel.d.ts +0 -34
- package/dist/src/runner/mission-capability-kernel.d.ts.map +0 -1
- package/dist/src/runner/mission-capability-kernel.js +0 -158
- package/dist/src/runner/mission-capability-kernel.js.map +0 -1
- package/dist/src/runner/mission-check-policy.d.ts +0 -17
- package/dist/src/runner/mission-check-policy.d.ts.map +0 -1
- package/dist/src/runner/mission-check-policy.js +0 -31
- package/dist/src/runner/mission-check-policy.js.map +0 -1
- package/dist/src/runner/mission-coordinator-lock.d.ts.map +0 -1
- package/dist/src/runner/mission-coordinator-lock.js.map +0 -1
- package/dist/src/runner/mission-deployment.d.ts +0 -21
- package/dist/src/runner/mission-deployment.d.ts.map +0 -1
- package/dist/src/runner/mission-deployment.js +0 -108
- package/dist/src/runner/mission-deployment.js.map +0 -1
- package/dist/src/runner/mission-evaluation.d.ts +0 -61
- package/dist/src/runner/mission-evaluation.d.ts.map +0 -1
- package/dist/src/runner/mission-evaluation.js +0 -183
- package/dist/src/runner/mission-evaluation.js.map +0 -1
- package/dist/src/runner/mission-executor-probe.d.ts +0 -10
- package/dist/src/runner/mission-executor-probe.d.ts.map +0 -1
- package/dist/src/runner/mission-executor-probe.js +0 -180
- package/dist/src/runner/mission-executor-probe.js.map +0 -1
- package/dist/src/runner/mission-git-contracts.d.ts +0 -75
- package/dist/src/runner/mission-git-contracts.d.ts.map +0 -1
- package/dist/src/runner/mission-git-contracts.js +0 -201
- package/dist/src/runner/mission-git-contracts.js.map +0 -1
- package/dist/src/runner/mission-git-runtime-owner-ref.d.ts +0 -13
- package/dist/src/runner/mission-git-runtime-owner-ref.d.ts.map +0 -1
- package/dist/src/runner/mission-git-runtime-owner-ref.js +0 -111
- package/dist/src/runner/mission-git-runtime-owner-ref.js.map +0 -1
- package/dist/src/runner/mission-git-transaction.d.ts +0 -97
- package/dist/src/runner/mission-git-transaction.d.ts.map +0 -1
- package/dist/src/runner/mission-git-transaction.js +0 -1009
- package/dist/src/runner/mission-git-transaction.js.map +0 -1
- package/dist/src/runner/mission-identifiers.d.ts +0 -31
- package/dist/src/runner/mission-identifiers.d.ts.map +0 -1
- package/dist/src/runner/mission-identifiers.js +0 -75
- package/dist/src/runner/mission-identifiers.js.map +0 -1
- package/dist/src/runner/mission-input-snapshot.d.ts +0 -21
- package/dist/src/runner/mission-input-snapshot.d.ts.map +0 -1
- package/dist/src/runner/mission-input-snapshot.js +0 -63
- package/dist/src/runner/mission-input-snapshot.js.map +0 -1
- package/dist/src/runner/mission-ownership.d.ts +0 -38
- package/dist/src/runner/mission-ownership.d.ts.map +0 -1
- package/dist/src/runner/mission-ownership.js +0 -88
- package/dist/src/runner/mission-ownership.js.map +0 -1
- package/dist/src/runner/mission-patch-audit.d.ts +0 -21
- package/dist/src/runner/mission-patch-audit.d.ts.map +0 -1
- package/dist/src/runner/mission-patch-audit.js +0 -186
- package/dist/src/runner/mission-patch-audit.js.map +0 -1
- package/dist/src/runner/mission-path-language.d.ts +0 -6
- package/dist/src/runner/mission-path-language.d.ts.map +0 -1
- package/dist/src/runner/mission-path-language.js +0 -106
- package/dist/src/runner/mission-path-language.js.map +0 -1
- package/dist/src/runner/mission-permit-authority.d.ts +0 -26
- package/dist/src/runner/mission-permit-authority.d.ts.map +0 -1
- package/dist/src/runner/mission-permit-authority.js +0 -145
- package/dist/src/runner/mission-permit-authority.js.map +0 -1
- package/dist/src/runner/mission-plan-parent-coordinator.d.ts +0 -87
- package/dist/src/runner/mission-plan-parent-coordinator.d.ts.map +0 -1
- package/dist/src/runner/mission-plan-parent-coordinator.js +0 -441
- package/dist/src/runner/mission-plan-parent-coordinator.js.map +0 -1
- package/dist/src/runner/mission-plan-parent.d.ts +0 -156
- package/dist/src/runner/mission-plan-parent.d.ts.map +0 -1
- package/dist/src/runner/mission-plan-parent.js +0 -589
- package/dist/src/runner/mission-plan-parent.js.map +0 -1
- package/dist/src/runner/mission-process-executor.d.ts +0 -25
- package/dist/src/runner/mission-process-executor.d.ts.map +0 -1
- package/dist/src/runner/mission-process-executor.js +0 -182
- package/dist/src/runner/mission-process-executor.js.map +0 -1
- package/dist/src/runner/mission-publication-git.d.ts +0 -21
- package/dist/src/runner/mission-publication-git.d.ts.map +0 -1
- package/dist/src/runner/mission-publication-git.js +0 -61
- package/dist/src/runner/mission-publication-git.js.map +0 -1
- package/dist/src/runner/mission-publication.d.ts +0 -192
- package/dist/src/runner/mission-publication.d.ts.map +0 -1
- package/dist/src/runner/mission-publication.js +0 -1001
- package/dist/src/runner/mission-publication.js.map +0 -1
- package/dist/src/runner/mission-quarantine-patch-executor.d.ts +0 -29
- package/dist/src/runner/mission-quarantine-patch-executor.d.ts.map +0 -1
- package/dist/src/runner/mission-quarantine-patch-executor.js +0 -121
- package/dist/src/runner/mission-quarantine-patch-executor.js.map +0 -1
- package/dist/src/runner/mission-repository-executor.d.ts +0 -54
- package/dist/src/runner/mission-repository-executor.d.ts.map +0 -1
- package/dist/src/runner/mission-repository-executor.js +0 -192
- package/dist/src/runner/mission-repository-executor.js.map +0 -1
- package/dist/src/runner/mission-repository-observer.d.ts +0 -8
- package/dist/src/runner/mission-repository-observer.d.ts.map +0 -1
- package/dist/src/runner/mission-repository-observer.js +0 -24
- package/dist/src/runner/mission-repository-observer.js.map +0 -1
- package/dist/src/runner/mission-reservations.d.ts +0 -15
- package/dist/src/runner/mission-reservations.d.ts.map +0 -1
- package/dist/src/runner/mission-reservations.js +0 -116
- package/dist/src/runner/mission-reservations.js.map +0 -1
- package/dist/src/runner/mission-resolution-loop.d.ts +0 -172
- package/dist/src/runner/mission-resolution-loop.d.ts.map +0 -1
- package/dist/src/runner/mission-resolution-loop.js +0 -318
- package/dist/src/runner/mission-resolution-loop.js.map +0 -1
- package/dist/src/runner/mission-runtime-owner.d.ts +0 -36
- package/dist/src/runner/mission-runtime-owner.d.ts.map +0 -1
- package/dist/src/runner/mission-runtime-owner.js +0 -174
- package/dist/src/runner/mission-runtime-owner.js.map +0 -1
- package/dist/src/runner/mission-safe-executor.d.ts +0 -96
- package/dist/src/runner/mission-safe-executor.d.ts.map +0 -1
- package/dist/src/runner/mission-safe-executor.js +0 -288
- package/dist/src/runner/mission-safe-executor.js.map +0 -1
- package/dist/src/runner/mission-sandbox.d.ts +0 -16
- package/dist/src/runner/mission-sandbox.d.ts.map +0 -1
- package/dist/src/runner/mission-sandbox.js +0 -91
- package/dist/src/runner/mission-sandbox.js.map +0 -1
- package/dist/src/runner/mission-scheduler.d.ts +0 -57
- package/dist/src/runner/mission-scheduler.d.ts.map +0 -1
- package/dist/src/runner/mission-scheduler.js +0 -205
- package/dist/src/runner/mission-scheduler.js.map +0 -1
- package/dist/src/runner/mission-scope-expansion.d.ts +0 -47
- package/dist/src/runner/mission-scope-expansion.d.ts.map +0 -1
- package/dist/src/runner/mission-scope-expansion.js +0 -147
- package/dist/src/runner/mission-scope-expansion.js.map +0 -1
- package/dist/src/runner/mission-state-machine.d.ts +0 -118
- package/dist/src/runner/mission-state-machine.d.ts.map +0 -1
- package/dist/src/runner/mission-state-machine.js +0 -316
- package/dist/src/runner/mission-state-machine.js.map +0 -1
- package/dist/src/runner/mission-state-store.d.ts +0 -70
- package/dist/src/runner/mission-state-store.d.ts.map +0 -1
- package/dist/src/runner/mission-state-store.js +0 -916
- package/dist/src/runner/mission-state-store.js.map +0 -1
- package/dist/src/runner/mobile-device-lease.d.ts +0 -11
- package/dist/src/runner/mobile-device-lease.d.ts.map +0 -1
- package/dist/src/runner/mobile-device-lease.js +0 -121
- package/dist/src/runner/mobile-device-lease.js.map +0 -1
- package/dist/src/runner/mobile-visual-proof-command.d.ts +0 -17
- package/dist/src/runner/mobile-visual-proof-command.d.ts.map +0 -1
- package/dist/src/runner/mobile-visual-proof-command.js +0 -168
- package/dist/src/runner/mobile-visual-proof-command.js.map +0 -1
- package/dist/src/runner/plan-auto-command.d.ts +0 -35
- package/dist/src/runner/plan-auto-command.d.ts.map +0 -1
- package/dist/src/runner/plan-auto-command.js +0 -918
- package/dist/src/runner/plan-auto-command.js.map +0 -1
- package/dist/src/runner/plan-auto-recovery.d.ts +0 -83
- package/dist/src/runner/plan-auto-recovery.d.ts.map +0 -1
- package/dist/src/runner/plan-auto-recovery.js +0 -303
- package/dist/src/runner/plan-auto-recovery.js.map +0 -1
- package/dist/src/runner/prompt.d.ts +0 -68
- package/dist/src/runner/prompt.d.ts.map +0 -1
- package/dist/src/runner/prompt.js +0 -202
- package/dist/src/runner/prompt.js.map +0 -1
- package/dist/src/runner/proof-routing.d.ts +0 -73
- package/dist/src/runner/proof-routing.d.ts.map +0 -1
- package/dist/src/runner/proof-routing.js +0 -182
- package/dist/src/runner/proof-routing.js.map +0 -1
- package/dist/src/runner/proof-strategy.d.ts +0 -21
- package/dist/src/runner/proof-strategy.d.ts.map +0 -1
- package/dist/src/runner/proof-strategy.js +0 -26
- package/dist/src/runner/proof-strategy.js.map +0 -1
- package/dist/src/runner/recovery.d.ts +0 -25
- package/dist/src/runner/recovery.d.ts.map +0 -1
- package/dist/src/runner/recovery.js +0 -89
- package/dist/src/runner/recovery.js.map +0 -1
- package/dist/src/runner/review-gate-policy.d.ts +0 -13
- package/dist/src/runner/review-gate-policy.d.ts.map +0 -1
- package/dist/src/runner/review-gate-policy.js +0 -241
- package/dist/src/runner/review-gate-policy.js.map +0 -1
- package/dist/src/runner/review-gates.d.ts +0 -28
- package/dist/src/runner/review-gates.d.ts.map +0 -1
- package/dist/src/runner/review-gates.js +0 -328
- package/dist/src/runner/review-gates.js.map +0 -1
- package/dist/src/runner/rework-policy.d.ts +0 -48
- package/dist/src/runner/rework-policy.d.ts.map +0 -1
- package/dist/src/runner/rework-policy.js +0 -150
- package/dist/src/runner/rework-policy.js.map +0 -1
- package/dist/src/runner/run-log.d.ts +0 -18
- package/dist/src/runner/run-log.d.ts.map +0 -1
- package/dist/src/runner/run-log.js +0 -53
- package/dist/src/runner/run-log.js.map +0 -1
- package/dist/src/runner/runner-handoff-decision.d.ts +0 -48
- package/dist/src/runner/runner-handoff-decision.d.ts.map +0 -1
- package/dist/src/runner/runner-handoff-decision.js +0 -93
- package/dist/src/runner/runner-handoff-decision.js.map +0 -1
- package/dist/src/runner/safety.d.ts +0 -14
- package/dist/src/runner/safety.d.ts.map +0 -1
- package/dist/src/runner/safety.js +0 -31
- package/dist/src/runner/safety.js.map +0 -1
- package/dist/src/runner/scope-isolation-policy.d.ts +0 -17
- package/dist/src/runner/scope-isolation-policy.d.ts.map +0 -1
- package/dist/src/runner/scope-isolation-policy.js +0 -82
- package/dist/src/runner/scope-isolation-policy.js.map +0 -1
- package/dist/src/runner/scoped-auto-command.d.ts +0 -90
- package/dist/src/runner/scoped-auto-command.d.ts.map +0 -1
- package/dist/src/runner/scoped-auto-command.js +0 -561
- package/dist/src/runner/scoped-auto-command.js.map +0 -1
- package/dist/src/runner/scoped-recovery.d.ts +0 -78
- package/dist/src/runner/scoped-recovery.d.ts.map +0 -1
- package/dist/src/runner/scoped-recovery.js +0 -601
- package/dist/src/runner/scoped-recovery.js.map +0 -1
- package/dist/src/runner/session-home.d.ts +0 -8
- package/dist/src/runner/session-home.d.ts.map +0 -1
- package/dist/src/runner/session-home.js +0 -18
- package/dist/src/runner/session-home.js.map +0 -1
- package/dist/src/runner/status-command.d.ts +0 -38
- package/dist/src/runner/status-command.d.ts.map +0 -1
- package/dist/src/runner/status-command.js +0 -97
- package/dist/src/runner/status-command.js.map +0 -1
- package/dist/src/runner/target-activity-fence.d.ts.map +0 -1
- package/dist/src/runner/target-activity-fence.js.map +0 -1
- package/dist/src/runner/terminal-outcome.d.ts +0 -58
- package/dist/src/runner/terminal-outcome.d.ts.map +0 -1
- package/dist/src/runner/terminal-outcome.js +0 -73
- package/dist/src/runner/terminal-outcome.js.map +0 -1
- package/dist/src/runner/visual-proof-runner.d.ts +0 -27
- package/dist/src/runner/visual-proof-runner.d.ts.map +0 -1
- package/dist/src/runner/visual-proof-runner.js +0 -379
- package/dist/src/runner/visual-proof-runner.js.map +0 -1
- package/dist/src/runner/worktree-cleanup.d.ts +0 -27
- package/dist/src/runner/worktree-cleanup.d.ts.map +0 -1
- package/dist/src/runner/worktree-cleanup.js +0 -63
- package/dist/src/runner/worktree-cleanup.js.map +0 -1
- package/dist/src/setup/codex-command-resolver.d.ts +0 -10
- package/dist/src/setup/codex-command-resolver.d.ts.map +0 -1
- package/dist/src/setup/codex-command-resolver.js +0 -91
- package/dist/src/setup/codex-command-resolver.js.map +0 -1
- package/dist/src/setup/github-label-adapter.d.ts +0 -13
- package/dist/src/setup/github-label-adapter.d.ts.map +0 -1
- package/dist/src/setup/github-label-adapter.js +0 -28
- package/dist/src/setup/github-label-adapter.js.map +0 -1
- package/dist/src/setup/labels.d.ts +0 -27
- package/dist/src/setup/labels.d.ts.map +0 -1
- package/dist/src/setup/labels.js +0 -42
- package/dist/src/setup/labels.js.map +0 -1
- package/dist/src/setup/project-config.d.ts +0 -24
- package/dist/src/setup/project-config.d.ts.map +0 -1
- package/dist/src/setup/project-config.js +0 -678
- package/dist/src/setup/project-config.js.map +0 -1
- package/dist/src/setup/prompt-sync.d.ts +0 -14
- package/dist/src/setup/prompt-sync.d.ts.map +0 -1
- package/dist/src/setup/prompt-sync.js +0 -228
- package/dist/src/setup/prompt-sync.js.map +0 -1
- package/dist/src/setup/setup-command.d.ts +0 -29
- package/dist/src/setup/setup-command.d.ts.map +0 -1
- package/dist/src/setup/setup-command.js +0 -304
- package/dist/src/setup/setup-command.js.map +0 -1
- package/dist/src/setup/skill-runtime-v2-preparation.d.ts +0 -56
- package/dist/src/setup/skill-runtime-v2-preparation.d.ts.map +0 -1
- package/dist/src/setup/skill-runtime-v2-preparation.js +0 -304
- package/dist/src/setup/skill-runtime-v2-preparation.js.map +0 -1
- package/dist/src/setup/workflows.d.ts +0 -10
- package/dist/src/setup/workflows.d.ts.map +0 -1
- package/dist/src/setup/workflows.js +0 -41
- package/dist/src/setup/workflows.js.map +0 -1
- package/prompts/setup-skill.md +0 -12
- package/prompts/workflows/acceptance-proof.md +0 -29
- package/prompts/workflows/breakdown-review.md +0 -48
- package/prompts/workflows/issue-breakdown.md +0 -155
- package/prompts/workflows/issue-tree-orchestration.md +0 -163
- package/prompts/workflows/prd.md +0 -80
- package/prompts/workflows/scoped-implementation.md +0 -129
- package/prompts/workflows/triage.md +0 -149
- /package/dist/src/{process → v2/adapters}/command.d.ts +0 -0
- /package/dist/src/{process → v2/adapters}/command.js +0 -0
- /package/dist/src/{fs → v2/adapters}/durable-atomic-file.d.ts +0 -0
- /package/dist/src/{fs → v2/adapters}/durable-atomic-file.js +0 -0
- /package/dist/src/{github → v2/adapters}/gh-cli.d.ts +0 -0
- /package/dist/src/{github → v2/adapters}/gh-cli.js +0 -0
- /package/dist/src/{github → v2/adapters}/gh-issue-adapter.d.ts +0 -0
- /package/dist/src/{github → v2/adapters}/gh-issue-adapter.js +0 -0
- /package/dist/src/{github → v2/adapters}/gh-pull-request-adapter.d.ts +0 -0
- /package/dist/src/{github → v2/adapters}/gh-pull-request-adapter.js +0 -0
- /package/dist/src/{github → v2/adapters}/issues.d.ts +0 -0
- /package/dist/src/{github → v2/adapters}/issues.js +0 -0
- /package/dist/src/{runner → v2/adapters}/mission-coordinator-lock.d.ts +0 -0
- /package/dist/src/{runner → v2/adapters}/mission-coordinator-lock.js +0 -0
- /package/dist/src/{path-policy.d.ts → v2/adapters/path-policy.d.ts} +0 -0
- /package/dist/src/{path-policy.js → v2/adapters/path-policy.js} +0 -0
- /package/dist/src/{github → v2/adapters}/pull-requests.d.ts +0 -0
- /package/dist/src/{github → v2/adapters}/pull-requests.js +0 -0
- /package/dist/src/{runner → v2/adapters}/target-activity-fence.d.ts +0 -0
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
import { posix } from 'node:path';
|
|
2
|
+
import { agentReportEnvelopeSchema } from './report-envelope.js';
|
|
3
|
+
const MAX_STRING_LENGTH = 16 * 1024;
|
|
4
|
+
const MAX_SUMMARY_LENGTH = 4 * 1024;
|
|
5
|
+
const MAX_ARRAY_LENGTH = 256;
|
|
6
|
+
const SHA256_PATTERN = /^[0-9a-f]{64}$/;
|
|
7
|
+
const SURFACES = ['non-visual', 'browser', 'android', 'ios'];
|
|
8
|
+
const TARGETS = ['browser', 'android', 'ios'];
|
|
9
|
+
const ARTIFACT_KINDS = [
|
|
10
|
+
'command-output', 'static-inspection', 'generated-file', 'screenshot',
|
|
11
|
+
'dom-snapshot', 'console-log', 'network-log', 'ui-hierarchy', 'device-log', 'lease-record',
|
|
12
|
+
];
|
|
13
|
+
export function validateProofReport(value) {
|
|
14
|
+
assertRecord(value, 'proof report');
|
|
15
|
+
const commonKeys = ['version', 'status', 'decision', 'criteria', 'checks', 'artifacts', 'findings', 'residualRisks'];
|
|
16
|
+
const visualReport = value.status !== 'external-block' && isRecord(value.decision) && value.decision.mode === 'visual';
|
|
17
|
+
if (value.status === 'passed' || value.status === 'needs-rework') {
|
|
18
|
+
assertExactObject(value, visualReport ? [...commonKeys, 'visualEvidence'] : commonKeys, 'proof report');
|
|
19
|
+
}
|
|
20
|
+
else if (value.status === 'external-block') {
|
|
21
|
+
assertExactObject(value, [...commonKeys, 'blocker'], 'proof report');
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
throw new Error('proof report.status is invalid');
|
|
25
|
+
}
|
|
26
|
+
if (value.version !== 1)
|
|
27
|
+
throw new Error('proof report.version must be 1');
|
|
28
|
+
validateDecision(value.decision);
|
|
29
|
+
validateCriteria(value.criteria, value.status);
|
|
30
|
+
validateChecks(value.checks, value.status);
|
|
31
|
+
validateArtifacts(value.artifacts);
|
|
32
|
+
assertStringArray(value.findings, 'proof report.findings');
|
|
33
|
+
assertStringArray(value.residualRisks, 'proof report.residualRisks');
|
|
34
|
+
if (value.status === 'passed' && value.findings.length !== 0)
|
|
35
|
+
throw new Error('passed proof report forbids findings');
|
|
36
|
+
if (value.status === 'needs-rework' && value.findings.length === 0)
|
|
37
|
+
throw new Error('needs-rework proof report requires findings');
|
|
38
|
+
if (value.status === 'external-block')
|
|
39
|
+
validateExternalBlocker(value.blocker, 'proof report.blocker');
|
|
40
|
+
const decision = value.decision;
|
|
41
|
+
const criteria = value.criteria;
|
|
42
|
+
if (decision.mode === 'non-visual') {
|
|
43
|
+
if (criteria.some((criterion) => criterion.surfaces.some((surface) => surface !== 'non-visual'))) {
|
|
44
|
+
throw new Error('non-visual proof may use only non-visual criterion surfaces');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const available = new Set(['non-visual', ...decision.targets]);
|
|
49
|
+
if (criteria.some((criterion) => criterion.surfaces.some((surface) => !available.has(surface)))) {
|
|
50
|
+
throw new Error('visual proof criterion surface is absent from decision targets');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (visualReport) {
|
|
54
|
+
validateVisualEvidence(value.visualEvidence, criteria, value.artifacts, decision);
|
|
55
|
+
}
|
|
56
|
+
const evidenceIds = new Set([
|
|
57
|
+
...value.checks.map((check) => check.id),
|
|
58
|
+
...value.artifacts.map((artifact) => artifact.id),
|
|
59
|
+
]);
|
|
60
|
+
for (const criterion of criteria) {
|
|
61
|
+
for (const ref of criterion.evidenceRefs) {
|
|
62
|
+
if (!evidenceIds.has(ref))
|
|
63
|
+
throw new Error(`criterion ${criterion.id} references unknown evidence ${ref}`);
|
|
64
|
+
}
|
|
65
|
+
if (value.status === 'passed' && criterion.evidenceRefs.length < criterion.surfaces.length) {
|
|
66
|
+
throw new Error(`passed criterion ${criterion.id} lacks evidence for every surface`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
export function createProofReceipt(input) {
|
|
72
|
+
assertBoundedString(input.proofId, 'proofId', MAX_STRING_LENGTH, true);
|
|
73
|
+
assertSha256(input.bindingSha256, 'bindingSha256');
|
|
74
|
+
assertBoundedString(input.summary, 'summary', MAX_SUMMARY_LENGTH, true);
|
|
75
|
+
assertBoundedString(input.localEvidenceId, 'localEvidenceId', MAX_STRING_LENGTH, true);
|
|
76
|
+
const report = validateProofReport(input.report);
|
|
77
|
+
return {
|
|
78
|
+
proofId: input.proofId,
|
|
79
|
+
bindingSha256: input.bindingSha256,
|
|
80
|
+
summary: input.summary,
|
|
81
|
+
publishableEvidence: report.artifacts
|
|
82
|
+
.filter((artifact) => artifact.publishable)
|
|
83
|
+
.map((artifact) => ({
|
|
84
|
+
ref: artifact.id,
|
|
85
|
+
kind: artifact.kind === 'screenshot' ? 'screenshot' : 'summary',
|
|
86
|
+
sha256: artifact.sha256,
|
|
87
|
+
description: artifact.description,
|
|
88
|
+
})),
|
|
89
|
+
localEvidenceId: input.localEvidenceId,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function proofReportOutputSchema() {
|
|
93
|
+
return agentReportEnvelopeSchema({
|
|
94
|
+
type: 'object',
|
|
95
|
+
additionalProperties: false,
|
|
96
|
+
required: [
|
|
97
|
+
'version', 'status', 'decision', 'criteria', 'checks', 'artifacts',
|
|
98
|
+
'visualEvidence', 'findings', 'residualRisks', 'blocker',
|
|
99
|
+
],
|
|
100
|
+
properties: {
|
|
101
|
+
version: { type: 'integer', const: 1 },
|
|
102
|
+
status: { type: 'string', enum: ['passed', 'needs-rework', 'external-block'] },
|
|
103
|
+
decision: decisionSchema(),
|
|
104
|
+
criteria: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: criterionSchema(false) },
|
|
105
|
+
checks: { type: 'array', maxItems: MAX_ARRAY_LENGTH, items: checkSchema(false) },
|
|
106
|
+
artifacts: { type: 'array', maxItems: MAX_ARRAY_LENGTH, items: artifactSchema() },
|
|
107
|
+
visualEvidence: {
|
|
108
|
+
anyOf: [browserVisualEvidenceSchema(), androidVisualEvidenceSchema(), iosVisualEvidenceSchema(), { type: 'null' }],
|
|
109
|
+
},
|
|
110
|
+
findings: stringArraySchema(),
|
|
111
|
+
residualRisks: stringArraySchema(),
|
|
112
|
+
blocker: { anyOf: [externalBlockerSchema(), { type: 'null' }] },
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
export function proofReportRepairDiagnostic(error) {
|
|
117
|
+
const detail = error instanceof Error ? error.message : 'unknown validation failure';
|
|
118
|
+
return `Return one complete JSON object matching the supplied proof output schema. Validation failed: ${detail}`;
|
|
119
|
+
}
|
|
120
|
+
export function proofReportSkillExcerpt() {
|
|
121
|
+
return 'Independently prove the frozen criteria and return only the JSON object required by the runner-supplied output schema. Do not edit product code, publish, or include credential/path material.';
|
|
122
|
+
}
|
|
123
|
+
function decisionSchema() {
|
|
124
|
+
return {
|
|
125
|
+
anyOf: [
|
|
126
|
+
nonVisualDecisionSchema(),
|
|
127
|
+
{
|
|
128
|
+
type: 'object',
|
|
129
|
+
additionalProperties: false,
|
|
130
|
+
required: ['mode', 'targets'],
|
|
131
|
+
properties: {
|
|
132
|
+
mode: { type: 'string', const: 'visual' },
|
|
133
|
+
targets: { type: 'array', minItems: 1, maxItems: TARGETS.length, items: { type: 'string', enum: TARGETS } },
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function nonVisualDecisionSchema() {
|
|
140
|
+
return {
|
|
141
|
+
type: 'object',
|
|
142
|
+
additionalProperties: false,
|
|
143
|
+
required: ['mode', 'targets'],
|
|
144
|
+
properties: {
|
|
145
|
+
mode: { type: 'string', const: 'non-visual' },
|
|
146
|
+
targets: { type: 'array', maxItems: 0, items: { type: 'string', enum: TARGETS } },
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function browserDecisionSchema() {
|
|
151
|
+
return {
|
|
152
|
+
type: 'object',
|
|
153
|
+
additionalProperties: false,
|
|
154
|
+
required: ['mode', 'targets'],
|
|
155
|
+
properties: {
|
|
156
|
+
mode: { type: 'string', const: 'visual' },
|
|
157
|
+
targets: { type: 'array', minItems: 1, maxItems: 1, items: { type: 'string', const: 'browser' } },
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function androidDecisionSchema() {
|
|
162
|
+
return {
|
|
163
|
+
type: 'object',
|
|
164
|
+
additionalProperties: false,
|
|
165
|
+
required: ['mode', 'targets'],
|
|
166
|
+
properties: {
|
|
167
|
+
mode: { type: 'string', const: 'visual' },
|
|
168
|
+
targets: { type: 'array', minItems: 1, maxItems: 1, items: { type: 'string', const: 'android' } },
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function iosDecisionSchema() {
|
|
173
|
+
return {
|
|
174
|
+
type: 'object',
|
|
175
|
+
additionalProperties: false,
|
|
176
|
+
required: ['mode', 'targets'],
|
|
177
|
+
properties: {
|
|
178
|
+
mode: { type: 'string', const: 'visual' },
|
|
179
|
+
targets: { type: 'array', minItems: 1, maxItems: 1, items: { type: 'string', const: 'ios' } },
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function criterionSchema(passed) {
|
|
184
|
+
return {
|
|
185
|
+
type: 'object',
|
|
186
|
+
additionalProperties: false,
|
|
187
|
+
required: ['id', 'status', 'confidence', 'surfaces', 'evidenceRefs', 'analysis'],
|
|
188
|
+
properties: {
|
|
189
|
+
id: boundedStringSchema(MAX_STRING_LENGTH),
|
|
190
|
+
status: passed ? { type: 'string', const: 'passed' } : { type: 'string', enum: ['passed', 'failed', 'unknown'] },
|
|
191
|
+
confidence: passed ? { type: 'string', const: 'high' } : { type: 'string', enum: ['high', 'medium', 'low'] },
|
|
192
|
+
surfaces: { type: 'array', minItems: 1, maxItems: SURFACES.length, items: { type: 'string', enum: SURFACES } },
|
|
193
|
+
evidenceRefs: {
|
|
194
|
+
type: 'array',
|
|
195
|
+
minItems: passed ? 1 : 0,
|
|
196
|
+
maxItems: MAX_ARRAY_LENGTH,
|
|
197
|
+
items: boundedStringSchema(MAX_STRING_LENGTH),
|
|
198
|
+
},
|
|
199
|
+
analysis: boundedStringSchema(MAX_SUMMARY_LENGTH),
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function checkSchema(passed) {
|
|
204
|
+
return {
|
|
205
|
+
type: 'object',
|
|
206
|
+
additionalProperties: false,
|
|
207
|
+
required: ['id', 'command', 'status', 'summary', 'outputSha256'],
|
|
208
|
+
properties: {
|
|
209
|
+
id: boundedStringSchema(MAX_STRING_LENGTH),
|
|
210
|
+
command: boundedStringSchema(MAX_STRING_LENGTH),
|
|
211
|
+
status: passed ? { type: 'string', const: 'passed' } : { type: 'string', enum: ['passed', 'failed'] },
|
|
212
|
+
summary: boundedStringSchema(MAX_SUMMARY_LENGTH),
|
|
213
|
+
outputSha256: sha256Schema(),
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function artifactSchema() {
|
|
218
|
+
return {
|
|
219
|
+
type: 'object',
|
|
220
|
+
additionalProperties: false,
|
|
221
|
+
required: ['id', 'kind', 'relativePath', 'sha256', 'publishable', 'description'],
|
|
222
|
+
properties: {
|
|
223
|
+
id: boundedStringSchema(MAX_STRING_LENGTH),
|
|
224
|
+
kind: { type: 'string', enum: ARTIFACT_KINDS },
|
|
225
|
+
relativePath: relativePathSchema(),
|
|
226
|
+
sha256: sha256Schema(),
|
|
227
|
+
publishable: { type: 'boolean' },
|
|
228
|
+
description: boundedStringSchema(MAX_SUMMARY_LENGTH),
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function browserVisualEvidenceSchema() {
|
|
233
|
+
const reviewSchema = {
|
|
234
|
+
type: 'array',
|
|
235
|
+
minItems: 1,
|
|
236
|
+
maxItems: MAX_ARRAY_LENGTH,
|
|
237
|
+
items: {
|
|
238
|
+
type: 'object',
|
|
239
|
+
additionalProperties: false,
|
|
240
|
+
required: ['summary', 'evidenceRefs'],
|
|
241
|
+
properties: {
|
|
242
|
+
summary: boundedStringSchema(MAX_SUMMARY_LENGTH),
|
|
243
|
+
evidenceRefs: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
return {
|
|
248
|
+
type: 'object',
|
|
249
|
+
additionalProperties: false,
|
|
250
|
+
required: ['workflow', 'captures', 'diagnostics', 'freshness', 'layoutReview', 'copyReview'],
|
|
251
|
+
properties: {
|
|
252
|
+
workflow: {
|
|
253
|
+
type: 'object', additionalProperties: false, required: ['entrypoint', 'steps', 'finalState'],
|
|
254
|
+
properties: {
|
|
255
|
+
entrypoint: boundedStringSchema(MAX_STRING_LENGTH),
|
|
256
|
+
steps: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
257
|
+
finalState: boundedStringSchema(MAX_SUMMARY_LENGTH),
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
captures: {
|
|
261
|
+
type: 'array', minItems: 2, maxItems: MAX_ARRAY_LENGTH,
|
|
262
|
+
items: {
|
|
263
|
+
type: 'object', additionalProperties: false,
|
|
264
|
+
required: ['target', 'name', 'width', 'height', 'criteriaRefs', 'screenshotRef', 'stateRef'],
|
|
265
|
+
properties: {
|
|
266
|
+
target: { type: 'string', const: 'browser' },
|
|
267
|
+
name: boundedStringSchema(MAX_STRING_LENGTH),
|
|
268
|
+
width: { type: 'integer' },
|
|
269
|
+
height: { type: 'integer' },
|
|
270
|
+
criteriaRefs: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
271
|
+
screenshotRef: boundedStringSchema(MAX_STRING_LENGTH),
|
|
272
|
+
stateRef: boundedStringSchema(MAX_STRING_LENGTH),
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
diagnostics: {
|
|
277
|
+
type: 'object', additionalProperties: false, required: ['consoleRef', 'networkRef'],
|
|
278
|
+
properties: { consoleRef: boundedStringSchema(MAX_STRING_LENGTH), networkRef: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
279
|
+
},
|
|
280
|
+
freshness: {
|
|
281
|
+
type: 'object', additionalProperties: false, required: ['capturedAfterFinalInteraction'],
|
|
282
|
+
properties: { capturedAfterFinalInteraction: { type: 'boolean', const: true } },
|
|
283
|
+
},
|
|
284
|
+
layoutReview: reviewSchema,
|
|
285
|
+
copyReview: reviewSchema,
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function androidVisualEvidenceSchema() {
|
|
290
|
+
return mobileVisualEvidenceSchema('android');
|
|
291
|
+
}
|
|
292
|
+
function iosVisualEvidenceSchema() {
|
|
293
|
+
return mobileVisualEvidenceSchema('ios');
|
|
294
|
+
}
|
|
295
|
+
function mobileVisualEvidenceSchema(target) {
|
|
296
|
+
const reviewSchema = {
|
|
297
|
+
type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH,
|
|
298
|
+
items: {
|
|
299
|
+
type: 'object', additionalProperties: false, required: ['summary', 'evidenceRefs'],
|
|
300
|
+
properties: {
|
|
301
|
+
summary: boundedStringSchema(MAX_SUMMARY_LENGTH),
|
|
302
|
+
evidenceRefs: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
return {
|
|
307
|
+
type: 'object',
|
|
308
|
+
additionalProperties: false,
|
|
309
|
+
required: ['workflow', 'captures', 'diagnostics', 'lease', 'freshness', 'layoutReview', 'copyReview'],
|
|
310
|
+
properties: {
|
|
311
|
+
workflow: {
|
|
312
|
+
type: 'object', additionalProperties: false, required: ['entrypoint', 'steps', 'finalState'],
|
|
313
|
+
properties: {
|
|
314
|
+
entrypoint: boundedStringSchema(MAX_STRING_LENGTH),
|
|
315
|
+
steps: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
316
|
+
finalState: boundedStringSchema(MAX_SUMMARY_LENGTH),
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
captures: {
|
|
320
|
+
type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH,
|
|
321
|
+
items: {
|
|
322
|
+
type: 'object', additionalProperties: false,
|
|
323
|
+
required: ['target', 'name', 'width', 'height', 'criteriaRefs', 'screenshotRef', 'stateRef'],
|
|
324
|
+
properties: {
|
|
325
|
+
target: { type: 'string', const: target },
|
|
326
|
+
name: boundedStringSchema(MAX_STRING_LENGTH),
|
|
327
|
+
width: { type: 'integer' },
|
|
328
|
+
height: { type: 'integer' },
|
|
329
|
+
criteriaRefs: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
330
|
+
screenshotRef: boundedStringSchema(MAX_STRING_LENGTH),
|
|
331
|
+
stateRef: boundedStringSchema(MAX_STRING_LENGTH),
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
diagnostics: {
|
|
336
|
+
type: 'object', additionalProperties: false, required: ['deviceLogRef'],
|
|
337
|
+
properties: { deviceLogRef: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
338
|
+
},
|
|
339
|
+
lease: {
|
|
340
|
+
type: 'object', additionalProperties: false, required: ['leaseRef'],
|
|
341
|
+
properties: { leaseRef: boundedStringSchema(MAX_STRING_LENGTH) },
|
|
342
|
+
},
|
|
343
|
+
freshness: {
|
|
344
|
+
type: 'object', additionalProperties: false, required: ['capturedAfterFinalInteraction'],
|
|
345
|
+
properties: { capturedAfterFinalInteraction: { type: 'boolean', const: true } },
|
|
346
|
+
},
|
|
347
|
+
layoutReview: reviewSchema,
|
|
348
|
+
copyReview: reviewSchema,
|
|
349
|
+
},
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function validateDecision(value) {
|
|
353
|
+
assertExactObject(value, ['mode', 'targets'], 'proof report.decision');
|
|
354
|
+
if (value.mode !== 'non-visual' && value.mode !== 'visual')
|
|
355
|
+
throw new Error('proof report.decision.mode is invalid');
|
|
356
|
+
assertEnumArray(value.targets, TARGETS, 'proof report.decision.targets');
|
|
357
|
+
if (value.mode === 'non-visual' && value.targets.length !== 0)
|
|
358
|
+
throw new Error('non-visual decision forbids targets');
|
|
359
|
+
if (value.mode === 'visual' && value.targets.length === 0)
|
|
360
|
+
throw new Error('visual decision requires targets');
|
|
361
|
+
}
|
|
362
|
+
function validateCriteria(value, reportStatus) {
|
|
363
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > MAX_ARRAY_LENGTH) {
|
|
364
|
+
throw new Error('proof report.criteria must contain 1 to 256 entries');
|
|
365
|
+
}
|
|
366
|
+
const ids = [];
|
|
367
|
+
for (const [index, criterion] of value.entries()) {
|
|
368
|
+
const field = `proof report.criteria[${index}]`;
|
|
369
|
+
assertExactObject(criterion, ['id', 'status', 'confidence', 'surfaces', 'evidenceRefs', 'analysis'], field);
|
|
370
|
+
assertBoundedString(criterion.id, `${field}.id`, MAX_STRING_LENGTH, true);
|
|
371
|
+
if (!['passed', 'failed', 'unknown'].includes(criterion.status))
|
|
372
|
+
throw new Error(`${field}.status is invalid`);
|
|
373
|
+
if (!['high', 'medium', 'low'].includes(criterion.confidence))
|
|
374
|
+
throw new Error(`${field}.confidence is invalid`);
|
|
375
|
+
assertEnumArray(criterion.surfaces, SURFACES, `${field}.surfaces`, true);
|
|
376
|
+
assertStringArray(criterion.evidenceRefs, `${field}.evidenceRefs`);
|
|
377
|
+
assertUnique(criterion.evidenceRefs, `${field}.evidenceRefs`);
|
|
378
|
+
assertBoundedString(criterion.analysis, `${field}.analysis`, MAX_SUMMARY_LENGTH, true);
|
|
379
|
+
if (reportStatus === 'passed' && (criterion.status !== 'passed' || criterion.confidence !== 'high')) {
|
|
380
|
+
throw new Error('passed proof requires every criterion passed with high confidence');
|
|
381
|
+
}
|
|
382
|
+
if (reportStatus === 'passed' && criterion.evidenceRefs.length === 0) {
|
|
383
|
+
throw new Error('passed proof requires criterion evidence');
|
|
384
|
+
}
|
|
385
|
+
ids.push(criterion.id);
|
|
386
|
+
}
|
|
387
|
+
assertUnique(ids, 'proof report.criteria ids');
|
|
388
|
+
}
|
|
389
|
+
function validateChecks(value, reportStatus) {
|
|
390
|
+
if (!Array.isArray(value) || value.length > MAX_ARRAY_LENGTH)
|
|
391
|
+
throw new Error('proof report.checks must contain at most 256 entries');
|
|
392
|
+
const ids = [];
|
|
393
|
+
for (const [index, check] of value.entries()) {
|
|
394
|
+
const field = `proof report.checks[${index}]`;
|
|
395
|
+
assertExactObject(check, ['id', 'command', 'status', 'summary', 'outputSha256'], field);
|
|
396
|
+
assertBoundedString(check.id, `${field}.id`, MAX_STRING_LENGTH, true);
|
|
397
|
+
assertBoundedString(check.command, `${field}.command`, MAX_STRING_LENGTH, true);
|
|
398
|
+
if (check.status !== 'passed' && check.status !== 'failed')
|
|
399
|
+
throw new Error(`${field}.status is invalid`);
|
|
400
|
+
if (reportStatus === 'passed' && check.status !== 'passed')
|
|
401
|
+
throw new Error('passed proof forbids failed checks');
|
|
402
|
+
assertBoundedString(check.summary, `${field}.summary`, MAX_SUMMARY_LENGTH, true);
|
|
403
|
+
assertSha256(check.outputSha256, `${field}.outputSha256`);
|
|
404
|
+
ids.push(check.id);
|
|
405
|
+
}
|
|
406
|
+
assertUnique(ids, 'proof report.check ids');
|
|
407
|
+
}
|
|
408
|
+
function validateArtifacts(value) {
|
|
409
|
+
if (!Array.isArray(value) || value.length > MAX_ARRAY_LENGTH)
|
|
410
|
+
throw new Error('proof report.artifacts must contain at most 256 entries');
|
|
411
|
+
const ids = [];
|
|
412
|
+
for (const [index, artifact] of value.entries()) {
|
|
413
|
+
const field = `proof report.artifacts[${index}]`;
|
|
414
|
+
assertExactObject(artifact, ['id', 'kind', 'relativePath', 'sha256', 'publishable', 'description'], field);
|
|
415
|
+
assertBoundedString(artifact.id, `${field}.id`, MAX_STRING_LENGTH, true);
|
|
416
|
+
if (!ARTIFACT_KINDS.includes(artifact.kind)) {
|
|
417
|
+
throw new Error(`${field}.kind is invalid`);
|
|
418
|
+
}
|
|
419
|
+
assertRelativePath(artifact.relativePath, `${field}.relativePath`);
|
|
420
|
+
assertSha256(artifact.sha256, `${field}.sha256`);
|
|
421
|
+
if (typeof artifact.publishable !== 'boolean')
|
|
422
|
+
throw new Error(`${field}.publishable must be boolean`);
|
|
423
|
+
if (artifact.publishable && artifact.kind !== 'screenshot' && artifact.kind !== 'generated-file') {
|
|
424
|
+
throw new Error('only screenshots or sanitized generated summaries may be publishable');
|
|
425
|
+
}
|
|
426
|
+
if (['dom-snapshot', 'console-log', 'network-log', 'ui-hierarchy', 'device-log', 'lease-record'].includes(artifact.kind)
|
|
427
|
+
&& artifact.publishable !== false) {
|
|
428
|
+
throw new Error(`${field}.kind must remain local-only`);
|
|
429
|
+
}
|
|
430
|
+
assertBoundedString(artifact.description, `${field}.description`, MAX_SUMMARY_LENGTH, true);
|
|
431
|
+
ids.push(artifact.id);
|
|
432
|
+
}
|
|
433
|
+
assertUnique(ids, 'proof report.artifact ids');
|
|
434
|
+
}
|
|
435
|
+
function validateVisualEvidence(value, criteria, artifacts, decision) {
|
|
436
|
+
if (decision.targets.length !== 1)
|
|
437
|
+
throw new Error('visual proof requires one settled platform target');
|
|
438
|
+
if (decision.targets[0] === 'browser')
|
|
439
|
+
return validateBrowserVisualEvidence(value, criteria, artifacts, decision);
|
|
440
|
+
if (decision.targets[0] === 'android')
|
|
441
|
+
return validateAndroidVisualEvidence(value, criteria, artifacts, decision);
|
|
442
|
+
if (decision.targets[0] === 'ios')
|
|
443
|
+
return validateIosVisualEvidence(value, criteria, artifacts, decision);
|
|
444
|
+
throw new Error('visual proof target is not implemented');
|
|
445
|
+
}
|
|
446
|
+
function validateBrowserVisualEvidence(value, criteria, artifacts, decision) {
|
|
447
|
+
if (decision.targets.length !== 1 || decision.targets[0] !== 'browser') {
|
|
448
|
+
throw new Error('Spec 3 visual proof supports the browser target only');
|
|
449
|
+
}
|
|
450
|
+
assertExactObject(value, ['workflow', 'captures', 'diagnostics', 'freshness', 'layoutReview', 'copyReview'], 'proof report.visualEvidence');
|
|
451
|
+
assertExactObject(value.workflow, ['entrypoint', 'steps', 'finalState'], 'proof report.visualEvidence.workflow');
|
|
452
|
+
assertBoundedString(value.workflow.entrypoint, 'proof report.visualEvidence.workflow.entrypoint', MAX_STRING_LENGTH, true);
|
|
453
|
+
if (!/^https?:\/\//u.test(value.workflow.entrypoint))
|
|
454
|
+
throw new Error('visual workflow entrypoint must be HTTP(S)');
|
|
455
|
+
assertStringArray(value.workflow.steps, 'proof report.visualEvidence.workflow.steps');
|
|
456
|
+
if (value.workflow.steps.length === 0)
|
|
457
|
+
throw new Error('visual workflow requires steps');
|
|
458
|
+
assertBoundedString(value.workflow.finalState, 'proof report.visualEvidence.workflow.finalState', MAX_SUMMARY_LENGTH, true);
|
|
459
|
+
const artifactById = new Map(artifacts.map((artifact) => [artifact.id, artifact]));
|
|
460
|
+
const browserCriteria = criteria.filter((criterion) => criterion.surfaces.includes('browser'));
|
|
461
|
+
const browserCriterionIds = new Set(browserCriteria.map((criterion) => criterion.id));
|
|
462
|
+
if (browserCriteria.length === 0)
|
|
463
|
+
throw new Error('browser decision requires a browser criterion surface');
|
|
464
|
+
if (!Array.isArray(value.captures) || value.captures.length < 2 || value.captures.length > MAX_ARRAY_LENGTH) {
|
|
465
|
+
throw new Error('browser visual evidence requires at least two captures');
|
|
466
|
+
}
|
|
467
|
+
const captureNames = [];
|
|
468
|
+
for (const [index, capture] of value.captures.entries()) {
|
|
469
|
+
const field = `proof report.visualEvidence.captures[${index}]`;
|
|
470
|
+
assertExactObject(capture, ['target', 'name', 'width', 'height', 'criteriaRefs', 'screenshotRef', 'stateRef'], field);
|
|
471
|
+
if (capture.target !== 'browser')
|
|
472
|
+
throw new Error(`${field}.target must be browser`);
|
|
473
|
+
assertBoundedString(capture.name, `${field}.name`, MAX_STRING_LENGTH, true);
|
|
474
|
+
if (!Number.isSafeInteger(capture.width) || !Number.isSafeInteger(capture.height)
|
|
475
|
+
|| capture.width < 1 || capture.height < 1
|
|
476
|
+
|| capture.width > 10_000 || capture.height > 10_000) {
|
|
477
|
+
throw new Error(`${field} dimensions are invalid`);
|
|
478
|
+
}
|
|
479
|
+
assertStringArray(capture.criteriaRefs, `${field}.criteriaRefs`);
|
|
480
|
+
assertUnique(capture.criteriaRefs, `${field}.criteriaRefs`);
|
|
481
|
+
if (capture.criteriaRefs.length === 0 || capture.criteriaRefs.some((id) => !browserCriterionIds.has(id))) {
|
|
482
|
+
throw new Error(`${field} has irrelevant criterion mapping`);
|
|
483
|
+
}
|
|
484
|
+
for (const criterionId of browserCriterionIds) {
|
|
485
|
+
if (!capture.criteriaRefs.includes(criterionId))
|
|
486
|
+
throw new Error(`${field} omits browser criterion ${criterionId}`);
|
|
487
|
+
}
|
|
488
|
+
assertBoundedString(capture.screenshotRef, `${field}.screenshotRef`, MAX_STRING_LENGTH, true);
|
|
489
|
+
assertBoundedString(capture.stateRef, `${field}.stateRef`, MAX_STRING_LENGTH, true);
|
|
490
|
+
const screenshot = artifactById.get(capture.screenshotRef);
|
|
491
|
+
const state = artifactById.get(capture.stateRef);
|
|
492
|
+
if (screenshot?.kind !== 'screenshot')
|
|
493
|
+
throw new Error(`${field} lacks screenshot evidence`);
|
|
494
|
+
if (state?.kind !== 'dom-snapshot')
|
|
495
|
+
throw new Error(`${field} lacks DOM state evidence`);
|
|
496
|
+
for (const criterionId of capture.criteriaRefs) {
|
|
497
|
+
const criterion = browserCriteria.find((candidate) => candidate.id === criterionId);
|
|
498
|
+
if (!criterion.evidenceRefs.includes(screenshot.id) || !criterion.evidenceRefs.includes(state.id)) {
|
|
499
|
+
throw new Error(`${field} evidence is not linked to criterion ${criterionId}`);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
captureNames.push(capture.name);
|
|
503
|
+
}
|
|
504
|
+
assertUnique(captureNames, 'proof report.visualEvidence capture names');
|
|
505
|
+
if (!value.captures.some((capture) => capture.width >= 1024)) {
|
|
506
|
+
throw new Error('browser visual evidence lacks desktop coverage');
|
|
507
|
+
}
|
|
508
|
+
if (!value.captures.some((capture) => capture.width <= 480)) {
|
|
509
|
+
throw new Error('browser visual evidence lacks narrow responsive coverage');
|
|
510
|
+
}
|
|
511
|
+
assertExactObject(value.diagnostics, ['consoleRef', 'networkRef'], 'proof report.visualEvidence.diagnostics');
|
|
512
|
+
if (artifactById.get(value.diagnostics.consoleRef)?.kind !== 'console-log') {
|
|
513
|
+
throw new Error('browser visual evidence lacks console diagnostics');
|
|
514
|
+
}
|
|
515
|
+
if (artifactById.get(value.diagnostics.networkRef)?.kind !== 'network-log') {
|
|
516
|
+
throw new Error('browser visual evidence lacks network diagnostics');
|
|
517
|
+
}
|
|
518
|
+
assertExactObject(value.freshness, ['capturedAfterFinalInteraction'], 'proof report.visualEvidence.freshness');
|
|
519
|
+
if (value.freshness.capturedAfterFinalInteraction !== true)
|
|
520
|
+
throw new Error('browser evidence is not post-interaction');
|
|
521
|
+
validateVisualReview(value.layoutReview, 'layoutReview', artifactById);
|
|
522
|
+
validateVisualReview(value.copyReview, 'copyReview', artifactById);
|
|
523
|
+
}
|
|
524
|
+
function validateAndroidVisualEvidence(value, criteria, artifacts, decision) {
|
|
525
|
+
validateMobileVisualEvidence(value, criteria, artifacts, decision, 'android');
|
|
526
|
+
}
|
|
527
|
+
function validateIosVisualEvidence(value, criteria, artifacts, decision) {
|
|
528
|
+
validateMobileVisualEvidence(value, criteria, artifacts, decision, 'ios');
|
|
529
|
+
}
|
|
530
|
+
function validateMobileVisualEvidence(value, criteria, artifacts, decision, target) {
|
|
531
|
+
if (decision.targets.length !== 1 || decision.targets[0] !== target)
|
|
532
|
+
throw new Error(`${target} visual target mismatch`);
|
|
533
|
+
assertExactObject(value, ['workflow', 'captures', 'diagnostics', 'lease', 'freshness', 'layoutReview', 'copyReview'], 'proof report.visualEvidence');
|
|
534
|
+
assertExactObject(value.workflow, ['entrypoint', 'steps', 'finalState'], 'proof report.visualEvidence.workflow');
|
|
535
|
+
assertBoundedString(value.workflow.entrypoint, 'proof report.visualEvidence.workflow.entrypoint', MAX_STRING_LENGTH, true);
|
|
536
|
+
assertStringArray(value.workflow.steps, 'proof report.visualEvidence.workflow.steps');
|
|
537
|
+
if (value.workflow.steps.length === 0)
|
|
538
|
+
throw new Error(`${target} visual workflow requires steps`);
|
|
539
|
+
assertBoundedString(value.workflow.finalState, 'proof report.visualEvidence.workflow.finalState', MAX_SUMMARY_LENGTH, true);
|
|
540
|
+
const artifactById = new Map(artifacts.map((artifact) => [artifact.id, artifact]));
|
|
541
|
+
const androidCriteria = criteria.filter((criterion) => criterion.surfaces.includes(target));
|
|
542
|
+
const androidCriterionIds = new Set(androidCriteria.map((criterion) => criterion.id));
|
|
543
|
+
if (androidCriteria.length === 0)
|
|
544
|
+
throw new Error(`${target} decision requires a ${target} criterion surface`);
|
|
545
|
+
if (!Array.isArray(value.captures) || value.captures.length === 0 || value.captures.length > MAX_ARRAY_LENGTH) {
|
|
546
|
+
throw new Error(`${target} visual evidence requires a capture`);
|
|
547
|
+
}
|
|
548
|
+
const captureNames = [];
|
|
549
|
+
for (const [index, capture] of value.captures.entries()) {
|
|
550
|
+
const field = `proof report.visualEvidence.captures[${index}]`;
|
|
551
|
+
assertExactObject(capture, ['target', 'name', 'width', 'height', 'criteriaRefs', 'screenshotRef', 'stateRef'], field);
|
|
552
|
+
if (capture.target !== target)
|
|
553
|
+
throw new Error(`${field}.target must be ${target}`);
|
|
554
|
+
assertBoundedString(capture.name, `${field}.name`, MAX_STRING_LENGTH, true);
|
|
555
|
+
if (!Number.isSafeInteger(capture.width) || !Number.isSafeInteger(capture.height)
|
|
556
|
+
|| capture.width < 1 || capture.height < 1
|
|
557
|
+
|| capture.width > 10_000 || capture.height > 10_000) {
|
|
558
|
+
throw new Error(`${field} dimensions are invalid`);
|
|
559
|
+
}
|
|
560
|
+
assertStringArray(capture.criteriaRefs, `${field}.criteriaRefs`);
|
|
561
|
+
assertUnique(capture.criteriaRefs, `${field}.criteriaRefs`);
|
|
562
|
+
if (capture.criteriaRefs.length === 0 || capture.criteriaRefs.some((id) => !androidCriterionIds.has(id))) {
|
|
563
|
+
throw new Error(`${field} has irrelevant criterion mapping`);
|
|
564
|
+
}
|
|
565
|
+
for (const criterionId of androidCriterionIds) {
|
|
566
|
+
if (!capture.criteriaRefs.includes(criterionId))
|
|
567
|
+
throw new Error(`${field} omits ${target} criterion ${criterionId}`);
|
|
568
|
+
}
|
|
569
|
+
assertBoundedString(capture.screenshotRef, `${field}.screenshotRef`, MAX_STRING_LENGTH, true);
|
|
570
|
+
assertBoundedString(capture.stateRef, `${field}.stateRef`, MAX_STRING_LENGTH, true);
|
|
571
|
+
const screenshot = artifactById.get(capture.screenshotRef);
|
|
572
|
+
const hierarchy = artifactById.get(capture.stateRef);
|
|
573
|
+
if (screenshot?.kind !== 'screenshot')
|
|
574
|
+
throw new Error(`${field} lacks screenshot evidence`);
|
|
575
|
+
if (hierarchy?.kind !== 'ui-hierarchy')
|
|
576
|
+
throw new Error(`${field} lacks UI hierarchy evidence`);
|
|
577
|
+
for (const criterionId of capture.criteriaRefs) {
|
|
578
|
+
const criterion = androidCriteria.find((candidate) => candidate.id === criterionId);
|
|
579
|
+
if (!criterion.evidenceRefs.includes(screenshot.id) || !criterion.evidenceRefs.includes(hierarchy.id)) {
|
|
580
|
+
throw new Error(`${field} evidence is not linked to criterion ${criterionId}`);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
captureNames.push(capture.name);
|
|
584
|
+
}
|
|
585
|
+
assertUnique(captureNames, 'proof report.visualEvidence capture names');
|
|
586
|
+
assertExactObject(value.diagnostics, ['deviceLogRef'], 'proof report.visualEvidence.diagnostics');
|
|
587
|
+
if (artifactById.get(value.diagnostics.deviceLogRef)?.kind !== 'device-log') {
|
|
588
|
+
throw new Error(`${target} visual evidence lacks device log diagnostics`);
|
|
589
|
+
}
|
|
590
|
+
assertExactObject(value.lease, ['leaseRef'], 'proof report.visualEvidence.lease');
|
|
591
|
+
if (artifactById.get(value.lease.leaseRef)?.kind !== 'lease-record') {
|
|
592
|
+
throw new Error(`${target} visual evidence lacks lease record`);
|
|
593
|
+
}
|
|
594
|
+
assertExactObject(value.freshness, ['capturedAfterFinalInteraction'], 'proof report.visualEvidence.freshness');
|
|
595
|
+
if (value.freshness.capturedAfterFinalInteraction !== true)
|
|
596
|
+
throw new Error(`${target} evidence is not post-interaction`);
|
|
597
|
+
validateVisualReview(value.layoutReview, 'layoutReview', artifactById);
|
|
598
|
+
validateVisualReview(value.copyReview, 'copyReview', artifactById);
|
|
599
|
+
}
|
|
600
|
+
function validateVisualReview(value, fieldName, artifactById) {
|
|
601
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > MAX_ARRAY_LENGTH) {
|
|
602
|
+
throw new Error(`proof report.visualEvidence.${fieldName} must be non-empty`);
|
|
603
|
+
}
|
|
604
|
+
for (const [index, finding] of value.entries()) {
|
|
605
|
+
const field = `proof report.visualEvidence.${fieldName}[${index}]`;
|
|
606
|
+
assertExactObject(finding, ['summary', 'evidenceRefs'], field);
|
|
607
|
+
assertBoundedString(finding.summary, `${field}.summary`, MAX_SUMMARY_LENGTH, true);
|
|
608
|
+
assertStringArray(finding.evidenceRefs, `${field}.evidenceRefs`);
|
|
609
|
+
assertUnique(finding.evidenceRefs, `${field}.evidenceRefs`);
|
|
610
|
+
if (finding.evidenceRefs.length === 0 || finding.evidenceRefs.some((ref) => !artifactById.has(ref))) {
|
|
611
|
+
throw new Error(`${field} has invalid evidence references`);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
function validateExternalBlocker(value, field) {
|
|
616
|
+
assertExactObject(value, ['kind', 'summary', 'attempted'], field);
|
|
617
|
+
if (!['credential', 'tool', 'service', 'product-decision'].includes(value.kind))
|
|
618
|
+
throw new Error(`${field}.kind is invalid`);
|
|
619
|
+
assertBoundedString(value.summary, `${field}.summary`, MAX_SUMMARY_LENGTH, true);
|
|
620
|
+
assertStringArray(value.attempted, `${field}.attempted`);
|
|
621
|
+
}
|
|
622
|
+
function externalBlockerSchema() {
|
|
623
|
+
return {
|
|
624
|
+
type: 'object',
|
|
625
|
+
additionalProperties: false,
|
|
626
|
+
required: ['kind', 'summary', 'attempted'],
|
|
627
|
+
properties: {
|
|
628
|
+
kind: { type: 'string', enum: ['credential', 'tool', 'service', 'product-decision'] },
|
|
629
|
+
summary: boundedStringSchema(MAX_SUMMARY_LENGTH),
|
|
630
|
+
attempted: stringArraySchema(),
|
|
631
|
+
},
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
function stringArraySchema() {
|
|
635
|
+
return { type: 'array', maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) };
|
|
636
|
+
}
|
|
637
|
+
function boundedStringSchema(maxLength) {
|
|
638
|
+
return { type: 'string', minLength: 1, maxLength };
|
|
639
|
+
}
|
|
640
|
+
function sha256Schema() {
|
|
641
|
+
return { type: 'string', pattern: '^[0-9a-f]{64}$' };
|
|
642
|
+
}
|
|
643
|
+
function relativePathSchema() {
|
|
644
|
+
return {
|
|
645
|
+
type: 'string',
|
|
646
|
+
minLength: 1,
|
|
647
|
+
maxLength: MAX_STRING_LENGTH,
|
|
648
|
+
pattern: '^[^/\\\\]$|^[^/\\\\][^\\\\]*[^/\\\\]$',
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
function assertRelativePath(value, field) {
|
|
652
|
+
assertBoundedString(value, field, MAX_STRING_LENGTH, true);
|
|
653
|
+
if (value.startsWith('/') || value.includes('\\') || posix.normalize(value) !== value) {
|
|
654
|
+
throw new Error(`${field} must be a normalized repository-relative POSIX path`);
|
|
655
|
+
}
|
|
656
|
+
const segments = value.split('/');
|
|
657
|
+
if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
|
|
658
|
+
throw new Error(`${field} must not contain empty, dot, or dot-dot segments`);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
function assertEnumArray(value, allowed, field, requireNonEmpty = false) {
|
|
662
|
+
if (!Array.isArray(value) || value.length > MAX_ARRAY_LENGTH || (requireNonEmpty && value.length === 0)) {
|
|
663
|
+
throw new Error(`${field} has invalid length`);
|
|
664
|
+
}
|
|
665
|
+
if (value.some((item) => typeof item !== 'string' || !allowed.includes(item)))
|
|
666
|
+
throw new Error(`${field} has invalid entries`);
|
|
667
|
+
assertUnique(value, field);
|
|
668
|
+
}
|
|
669
|
+
function assertStringArray(value, field) {
|
|
670
|
+
if (!Array.isArray(value) || value.length > MAX_ARRAY_LENGTH)
|
|
671
|
+
throw new Error(`${field} must contain at most 256 strings`);
|
|
672
|
+
for (const item of value)
|
|
673
|
+
assertBoundedString(item, `${field} entry`, MAX_STRING_LENGTH, true);
|
|
674
|
+
}
|
|
675
|
+
function assertUnique(values, field) {
|
|
676
|
+
if (new Set(values).size !== values.length)
|
|
677
|
+
throw new Error(`${field} must be unique`);
|
|
678
|
+
}
|
|
679
|
+
function assertSha256(value, field) {
|
|
680
|
+
if (typeof value !== 'string' || !SHA256_PATTERN.test(value))
|
|
681
|
+
throw new Error(`${field} must be lowercase SHA-256`);
|
|
682
|
+
}
|
|
683
|
+
function assertBoundedString(value, field, maxLength, requireNonEmpty) {
|
|
684
|
+
if (typeof value !== 'string' || value.length > maxLength || (requireNonEmpty && value.length === 0)) {
|
|
685
|
+
throw new Error(`${field} must be a bounded string`);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
function assertRecord(value, field) {
|
|
689
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
690
|
+
throw new Error(`${field} must be an object`);
|
|
691
|
+
}
|
|
692
|
+
function isRecord(value) {
|
|
693
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
694
|
+
}
|
|
695
|
+
function assertExactObject(value, keys, field) {
|
|
696
|
+
assertRecord(value, field);
|
|
697
|
+
const actual = Object.keys(value).sort();
|
|
698
|
+
const expected = [...keys].sort();
|
|
699
|
+
if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) {
|
|
700
|
+
throw new Error(`${field} has unknown or missing keys`);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
//# sourceMappingURL=proof-report.js.map
|