@prismatic-io/lux 0.0.2-preview.4 → 0.0.2-preview.40
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/lib/answerers/claude-code/index.d.ts +15 -3
- package/lib/answerers/claude-code/index.d.ts.map +1 -1
- package/lib/answerers/claude-code/index.js +6 -5
- package/lib/answerers/claude-code/index.js.map +1 -1
- package/lib/answerers/persona/index.d.ts +44 -5
- package/lib/answerers/persona/index.d.ts.map +1 -1
- package/lib/answerers/persona/index.js +60 -34
- package/lib/answerers/persona/index.js.map +1 -1
- package/lib/answerers/terminal/index.d.ts +9 -3
- package/lib/answerers/terminal/index.d.ts.map +1 -1
- package/lib/answerers/terminal/index.js +6 -4
- package/lib/answerers/terminal/index.js.map +1 -1
- package/lib/assertions/authoring.d.ts +2 -2
- package/lib/assertions/authoring.d.ts.map +1 -1
- package/lib/assertions/authoring.js.map +1 -1
- package/lib/assertions/core/command-exits-zero.d.ts +5 -2
- package/lib/assertions/core/command-exits-zero.d.ts.map +1 -1
- package/lib/assertions/core/command-exits-zero.js +59 -14
- package/lib/assertions/core/command-exits-zero.js.map +1 -1
- package/lib/assertions/core/event-checks.d.ts +3 -0
- package/lib/assertions/core/event-checks.d.ts.map +1 -1
- package/lib/assertions/core/event-checks.js +49 -3
- package/lib/assertions/core/event-checks.js.map +1 -1
- package/lib/assertions/core/file-checks.d.ts +6 -0
- package/lib/assertions/core/file-checks.d.ts.map +1 -1
- package/lib/assertions/core/index.d.ts.map +1 -1
- package/lib/assertions/core/index.js +2 -1
- package/lib/assertions/core/index.js.map +1 -1
- package/lib/assertions/core/json-pointer-equals.d.ts +1 -0
- package/lib/assertions/core/json-pointer-equals.d.ts.map +1 -1
- package/lib/assertions/core/output-checks.d.ts +3 -0
- package/lib/assertions/core/output-checks.d.ts.map +1 -1
- package/lib/assertions/core/predicate.d.ts +1 -0
- package/lib/assertions/core/predicate.d.ts.map +1 -1
- package/lib/assertions/core/resource-checks.d.ts +25 -0
- package/lib/assertions/core/resource-checks.d.ts.map +1 -1
- package/lib/assertions/core/resource-checks.js +35 -5
- package/lib/assertions/core/resource-checks.js.map +1 -1
- package/lib/assertions/core/safe-regex.d.ts.map +1 -1
- package/lib/assertions/core/safe-regex.js +7 -1
- package/lib/assertions/core/safe-regex.js.map +1 -1
- package/lib/assertions/rubric/evidence.d.ts +88 -0
- package/lib/assertions/rubric/evidence.d.ts.map +1 -0
- package/lib/assertions/rubric/evidence.js +75 -0
- package/lib/assertions/rubric/evidence.js.map +1 -0
- package/lib/assertions/rubric/index.d.ts +88 -34
- package/lib/assertions/rubric/index.d.ts.map +1 -1
- package/lib/assertions/rubric/index.js +59 -43
- package/lib/assertions/rubric/index.js.map +1 -1
- package/lib/assertions/rubric/internal.d.ts +30 -5
- package/lib/assertions/rubric/internal.d.ts.map +1 -1
- package/lib/assertions/rubric/internal.js +203 -41
- package/lib/assertions/rubric/internal.js.map +1 -1
- package/lib/authoring.d.ts +37 -2
- package/lib/authoring.d.ts.map +1 -1
- package/lib/authoring.js +36 -1
- package/lib/authoring.js.map +1 -1
- package/lib/cli/bin.js +2 -13
- package/lib/cli/bin.js.map +1 -1
- package/lib/cli/command-runtime.d.ts +3 -3
- package/lib/cli/command-runtime.d.ts.map +1 -1
- package/lib/cli/command-runtime.js +17 -6
- package/lib/cli/command-runtime.js.map +1 -1
- package/lib/cli/doctor.d.ts +55 -0
- package/lib/cli/doctor.d.ts.map +1 -0
- package/lib/cli/doctor.js +14 -0
- package/lib/cli/doctor.js.map +1 -0
- package/lib/cli/harness-plan.d.ts +27 -0
- package/lib/cli/harness-plan.d.ts.map +1 -0
- package/lib/cli/harness-plan.js +75 -0
- package/lib/cli/harness-plan.js.map +1 -0
- package/lib/cli/init-templates.d.ts +11 -0
- package/lib/cli/init-templates.d.ts.map +1 -0
- package/lib/cli/init-templates.js +215 -0
- package/lib/cli/init-templates.js.map +1 -0
- package/lib/cli/init.d.ts +10 -0
- package/lib/cli/init.d.ts.map +1 -1
- package/lib/cli/init.js +34 -173
- package/lib/cli/init.js.map +1 -1
- package/lib/cli/output-schemas.d.ts +1412 -0
- package/lib/cli/output-schemas.d.ts.map +1 -0
- package/lib/cli/output-schemas.js +94 -0
- package/lib/cli/output-schemas.js.map +1 -0
- package/lib/cli/program.d.ts +140 -12
- package/lib/cli/program.d.ts.map +1 -1
- package/lib/cli/program.js +783 -650
- package/lib/cli/program.js.map +1 -1
- package/lib/cli/render/format.d.ts.map +1 -1
- package/lib/cli/render/format.js +1 -1
- package/lib/cli/render/format.js.map +1 -1
- package/lib/cli/render/reporter.d.ts.map +1 -1
- package/lib/cli/render/reporter.js +35 -8
- package/lib/cli/render/reporter.js.map +1 -1
- package/lib/cli/run-options.d.ts +19 -4
- package/lib/cli/run-options.d.ts.map +1 -1
- package/lib/cli/run-options.js +100 -19
- package/lib/cli/run-options.js.map +1 -1
- package/lib/cli/view.d.ts +15 -0
- package/lib/cli/view.d.ts.map +1 -0
- package/lib/cli/view.js +168 -0
- package/lib/cli/view.js.map +1 -0
- package/lib/container/driver.d.ts +27 -0
- package/lib/container/driver.d.ts.map +1 -0
- package/lib/container/driver.js +199 -0
- package/lib/container/driver.js.map +1 -0
- package/lib/container/paths.d.ts +3 -0
- package/lib/container/paths.d.ts.map +1 -0
- package/lib/container/paths.js +27 -0
- package/lib/container/paths.js.map +1 -0
- package/lib/container/protocol.d.ts +12 -0
- package/lib/container/protocol.d.ts.map +1 -0
- package/lib/container/protocol.js +38 -0
- package/lib/container/protocol.js.map +1 -0
- package/lib/container/resources.d.ts +14 -0
- package/lib/container/resources.d.ts.map +1 -0
- package/lib/container/resources.js +141 -0
- package/lib/container/resources.js.map +1 -0
- package/lib/container/worker.d.ts +2 -0
- package/lib/container/worker.d.ts.map +1 -0
- package/lib/container/worker.js +85 -0
- package/lib/container/worker.js.map +1 -0
- package/lib/core/action-events.d.ts +29 -0
- package/lib/core/action-events.d.ts.map +1 -0
- package/lib/core/action-events.js +51 -0
- package/lib/core/action-events.js.map +1 -0
- package/lib/core/agent-activity.d.ts +49 -0
- package/lib/core/agent-activity.d.ts.map +1 -0
- package/lib/core/agent-activity.js +206 -0
- package/lib/core/agent-activity.js.map +1 -0
- package/lib/core/agent-environment.d.ts +5 -0
- package/lib/core/agent-environment.d.ts.map +1 -0
- package/lib/core/agent-environment.js +47 -0
- package/lib/core/agent-environment.js.map +1 -0
- package/lib/core/agent-events.d.ts +26 -0
- package/lib/core/agent-events.d.ts.map +1 -0
- package/lib/core/agent-events.js +13 -0
- package/lib/core/agent-events.js.map +1 -0
- package/lib/core/annotation.d.ts +6 -2
- package/lib/core/annotation.d.ts.map +1 -1
- package/lib/core/annotation.js +2 -1
- package/lib/core/annotation.js.map +1 -1
- package/lib/core/answerer.d.ts +12 -0
- package/lib/core/answerer.d.ts.map +1 -1
- package/lib/core/answerer.js +2 -0
- package/lib/core/answerer.js.map +1 -1
- package/lib/core/artifact-evidence.d.ts +6 -1
- package/lib/core/artifact-evidence.d.ts.map +1 -1
- package/lib/core/artifact-evidence.js +27 -6
- package/lib/core/artifact-evidence.js.map +1 -1
- package/lib/core/assertion.d.ts +10 -4
- package/lib/core/assertion.d.ts.map +1 -1
- package/lib/core/assertion.js +8 -2
- package/lib/core/assertion.js.map +1 -1
- package/lib/core/case-defaults.d.ts +16 -0
- package/lib/core/case-defaults.d.ts.map +1 -0
- package/lib/core/case-defaults.js +42 -0
- package/lib/core/case-defaults.js.map +1 -0
- package/lib/core/case.d.ts +120 -6
- package/lib/core/case.d.ts.map +1 -1
- package/lib/core/case.js +51 -5
- package/lib/core/case.js.map +1 -1
- package/lib/core/command-verification.d.ts +10 -0
- package/lib/core/command-verification.d.ts.map +1 -0
- package/lib/core/command-verification.js +66 -0
- package/lib/core/command-verification.js.map +1 -0
- package/lib/core/driver-execution.d.ts +83 -0
- package/lib/core/driver-execution.d.ts.map +1 -0
- package/lib/core/driver-execution.js +72 -0
- package/lib/core/driver-execution.js.map +1 -0
- package/lib/core/driver-metrics.d.ts +98 -0
- package/lib/core/driver-metrics.d.ts.map +1 -0
- package/lib/core/driver-metrics.js +36 -0
- package/lib/core/driver-metrics.js.map +1 -0
- package/lib/core/driver.d.ts +64 -0
- package/lib/core/driver.d.ts.map +1 -1
- package/lib/core/driver.js +28 -0
- package/lib/core/driver.js.map +1 -1
- package/lib/core/duration.d.ts +5 -0
- package/lib/core/duration.d.ts.map +1 -0
- package/lib/core/duration.js +49 -0
- package/lib/core/duration.js.map +1 -0
- package/lib/core/environment.d.ts +18 -0
- package/lib/core/environment.d.ts.map +1 -0
- package/lib/core/environment.js +21 -0
- package/lib/core/environment.js.map +1 -0
- package/lib/core/evaluation-clusters.d.ts +17 -0
- package/lib/core/evaluation-clusters.d.ts.map +1 -0
- package/lib/core/evaluation-clusters.js +23 -0
- package/lib/core/evaluation-clusters.js.map +1 -0
- package/lib/core/events.d.ts +34 -0
- package/lib/core/events.d.ts.map +1 -1
- package/lib/core/events.js +11 -2
- package/lib/core/events.js.map +1 -1
- package/lib/core/experiment.d.ts +33 -2
- package/lib/core/experiment.d.ts.map +1 -1
- package/lib/core/experiment.js +40 -19
- package/lib/core/experiment.js.map +1 -1
- package/lib/core/file-tree.d.ts +7 -0
- package/lib/core/file-tree.d.ts.map +1 -0
- package/lib/core/file-tree.js +35 -0
- package/lib/core/file-tree.js.map +1 -0
- package/lib/core/global-id.d.ts +6 -0
- package/lib/core/global-id.d.ts.map +1 -0
- package/lib/core/global-id.js +17 -0
- package/lib/core/global-id.js.map +1 -0
- package/lib/core/harness-catalog.d.ts +35 -0
- package/lib/core/harness-catalog.d.ts.map +1 -0
- package/lib/core/harness-catalog.js +45 -0
- package/lib/core/harness-catalog.js.map +1 -0
- package/lib/core/harness-catalogs/antigravity.d.ts +11 -0
- package/lib/core/harness-catalogs/antigravity.d.ts.map +1 -0
- package/lib/core/harness-catalogs/antigravity.js +23 -0
- package/lib/core/harness-catalogs/antigravity.js.map +1 -0
- package/lib/core/harness-catalogs/claude-code.d.ts +12 -0
- package/lib/core/harness-catalogs/claude-code.d.ts.map +1 -0
- package/lib/core/harness-catalogs/claude-code.js +24 -0
- package/lib/core/harness-catalogs/claude-code.js.map +1 -0
- package/lib/core/harness-catalogs/codex.d.ts +11 -0
- package/lib/core/harness-catalogs/codex.d.ts.map +1 -0
- package/lib/core/harness-catalogs/codex.js +26 -0
- package/lib/core/harness-catalogs/codex.js.map +1 -0
- package/lib/core/harness-catalogs/copilot.d.ts +29 -0
- package/lib/core/harness-catalogs/copilot.d.ts.map +1 -0
- package/lib/core/harness-catalogs/copilot.js +45 -0
- package/lib/core/harness-catalogs/copilot.js.map +1 -0
- package/lib/core/harness-catalogs/cursor.d.ts +2 -0
- package/lib/core/harness-catalogs/cursor.d.ts.map +1 -0
- package/lib/core/harness-catalogs/cursor.js +13 -0
- package/lib/core/harness-catalogs/cursor.js.map +1 -0
- package/lib/core/harness-catalogs/grok-build.d.ts +7 -0
- package/lib/core/harness-catalogs/grok-build.d.ts.map +1 -0
- package/lib/core/harness-catalogs/grok-build.js +18 -0
- package/lib/core/harness-catalogs/grok-build.js.map +1 -0
- package/lib/core/harness-catalogs/index.d.ts +73 -0
- package/lib/core/harness-catalogs/index.d.ts.map +1 -0
- package/lib/core/harness-catalogs/index.js +17 -0
- package/lib/core/harness-catalogs/index.js.map +1 -0
- package/lib/core/harness-matrix.d.ts +154 -0
- package/lib/core/harness-matrix.d.ts.map +1 -0
- package/lib/core/harness-matrix.js +204 -0
- package/lib/core/harness-matrix.js.map +1 -0
- package/lib/core/index.d.ts +12 -0
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +12 -0
- package/lib/core/index.js.map +1 -1
- package/lib/core/lifecycle-fixtures.d.ts.map +1 -1
- package/lib/core/lifecycle-fixtures.js +4 -2
- package/lib/core/lifecycle-fixtures.js.map +1 -1
- package/lib/core/model-cli.d.ts +9 -11
- package/lib/core/model-cli.d.ts.map +1 -1
- package/lib/core/model-cli.js +39 -22
- package/lib/core/model-cli.js.map +1 -1
- package/lib/core/platform-process.d.ts +7 -2
- package/lib/core/platform-process.d.ts.map +1 -1
- package/lib/core/platform-process.js +54 -16
- package/lib/core/platform-process.js.map +1 -1
- package/lib/core/reference-defaults.d.ts +5 -0
- package/lib/core/reference-defaults.d.ts.map +1 -0
- package/lib/core/reference-defaults.js +42 -0
- package/lib/core/reference-defaults.js.map +1 -0
- package/lib/core/rubric.d.ts +1 -0
- package/lib/core/rubric.d.ts.map +1 -1
- package/lib/core/run.d.ts +292 -1
- package/lib/core/run.d.ts.map +1 -1
- package/lib/core/run.js +27 -0
- package/lib/core/run.js.map +1 -1
- package/lib/core/secure-copy.d.ts.map +1 -0
- package/lib/core/secure-copy.js.map +1 -0
- package/lib/core/usage.d.ts +5 -0
- package/lib/core/usage.d.ts.map +1 -1
- package/lib/core/usage.js +3 -0
- package/lib/core/usage.js.map +1 -1
- package/lib/core/wire.d.ts +11 -0
- package/lib/core/wire.d.ts.map +1 -1
- package/lib/drivers/antigravity/artifacts.d.ts +2 -0
- package/lib/drivers/antigravity/artifacts.d.ts.map +1 -0
- package/lib/drivers/antigravity/artifacts.js +33 -0
- package/lib/drivers/antigravity/artifacts.js.map +1 -0
- package/lib/drivers/antigravity/config.d.ts +88 -0
- package/lib/drivers/antigravity/config.d.ts.map +1 -0
- package/lib/drivers/antigravity/config.js +87 -0
- package/lib/drivers/antigravity/config.js.map +1 -0
- package/lib/drivers/antigravity/events.d.ts +4 -0
- package/lib/drivers/antigravity/events.d.ts.map +1 -0
- package/lib/drivers/antigravity/events.js +241 -0
- package/lib/drivers/antigravity/events.js.map +1 -0
- package/lib/drivers/antigravity/index.d.ts +114 -0
- package/lib/drivers/antigravity/index.d.ts.map +1 -0
- package/lib/drivers/antigravity/index.js +113 -0
- package/lib/drivers/antigravity/index.js.map +1 -0
- package/lib/drivers/antigravity/runtime.d.ts +7 -0
- package/lib/drivers/antigravity/runtime.d.ts.map +1 -0
- package/lib/drivers/antigravity/runtime.js +83 -0
- package/lib/drivers/antigravity/runtime.js.map +1 -0
- package/lib/drivers/claude-code/deferred-process.d.ts +17 -0
- package/lib/drivers/claude-code/deferred-process.d.ts.map +1 -0
- package/lib/drivers/claude-code/deferred-process.js +108 -0
- package/lib/drivers/claude-code/deferred-process.js.map +1 -0
- package/lib/drivers/claude-code/index.d.ts +187 -10
- package/lib/drivers/claude-code/index.d.ts.map +1 -1
- package/lib/drivers/claude-code/index.js +197 -252
- package/lib/drivers/claude-code/index.js.map +1 -1
- package/lib/drivers/claude-code/isolation.d.ts +8 -0
- package/lib/drivers/claude-code/isolation.d.ts.map +1 -0
- package/lib/drivers/claude-code/isolation.js +199 -0
- package/lib/drivers/claude-code/isolation.js.map +1 -0
- package/lib/drivers/claude-code/parse-events.d.ts.map +1 -1
- package/lib/drivers/claude-code/parse-events.js +73 -8
- package/lib/drivers/claude-code/parse-events.js.map +1 -1
- package/lib/drivers/codex/app-events.d.ts +9 -2
- package/lib/drivers/codex/app-events.d.ts.map +1 -1
- package/lib/drivers/codex/app-events.js +104 -12
- package/lib/drivers/codex/app-events.js.map +1 -1
- package/lib/drivers/codex/config.d.ts +69 -5
- package/lib/drivers/codex/config.d.ts.map +1 -1
- package/lib/drivers/codex/config.js +48 -8
- package/lib/drivers/codex/config.js.map +1 -1
- package/lib/drivers/codex/exec-events.d.ts +4 -0
- package/lib/drivers/codex/exec-events.d.ts.map +1 -0
- package/lib/drivers/codex/exec-events.js +230 -0
- package/lib/drivers/codex/exec-events.js.map +1 -0
- package/lib/drivers/codex/index.d.ts +142 -4
- package/lib/drivers/codex/index.d.ts.map +1 -1
- package/lib/drivers/codex/index.js +114 -276
- package/lib/drivers/codex/index.js.map +1 -1
- package/lib/drivers/copilot/config.d.ts +84 -0
- package/lib/drivers/copilot/config.d.ts.map +1 -0
- package/lib/drivers/copilot/config.js +57 -0
- package/lib/drivers/copilot/config.js.map +1 -0
- package/lib/drivers/copilot/index.d.ts +107 -0
- package/lib/drivers/copilot/index.d.ts.map +1 -0
- package/lib/drivers/copilot/index.js +268 -0
- package/lib/drivers/copilot/index.js.map +1 -0
- package/lib/drivers/cursor/config.d.ts +28 -0
- package/lib/drivers/cursor/config.d.ts.map +1 -0
- package/lib/drivers/cursor/config.js +28 -0
- package/lib/drivers/cursor/config.js.map +1 -0
- package/lib/drivers/cursor/index.d.ts +44 -0
- package/lib/drivers/cursor/index.d.ts.map +1 -0
- package/lib/drivers/cursor/index.js +286 -0
- package/lib/drivers/cursor/index.js.map +1 -0
- package/lib/drivers/cursor/interaction.d.ts +6 -0
- package/lib/drivers/cursor/interaction.d.ts.map +1 -0
- package/lib/drivers/cursor/interaction.js +55 -0
- package/lib/drivers/cursor/interaction.js.map +1 -0
- package/lib/drivers/grok-build/config.d.ts +68 -0
- package/lib/drivers/grok-build/config.d.ts.map +1 -0
- package/lib/drivers/grok-build/config.js +40 -0
- package/lib/drivers/grok-build/config.js.map +1 -0
- package/lib/drivers/grok-build/index.d.ts +87 -0
- package/lib/drivers/grok-build/index.d.ts.map +1 -0
- package/lib/drivers/grok-build/index.js +293 -0
- package/lib/drivers/grok-build/index.js.map +1 -0
- package/lib/drivers/mcp/index.d.ts +37 -4
- package/lib/drivers/mcp/index.d.ts.map +1 -1
- package/lib/drivers/mcp/index.js +25 -11
- package/lib/drivers/mcp/index.js.map +1 -1
- package/lib/drivers/shared/acp-events.d.ts +15 -0
- package/lib/drivers/shared/acp-events.d.ts.map +1 -0
- package/lib/drivers/shared/acp-events.js +83 -0
- package/lib/drivers/shared/acp-events.js.map +1 -0
- package/lib/drivers/shared/acp-interaction.d.ts +7 -0
- package/lib/drivers/shared/acp-interaction.d.ts.map +1 -0
- package/lib/drivers/shared/acp-interaction.js +20 -0
- package/lib/drivers/shared/acp-interaction.js.map +1 -0
- package/lib/drivers/shared/acp-session.d.ts +4 -0
- package/lib/drivers/shared/acp-session.d.ts.map +1 -0
- package/lib/drivers/shared/acp-session.js +23 -0
- package/lib/drivers/shared/acp-session.js.map +1 -0
- package/lib/drivers/shared/acp-transport.d.ts +40 -0
- package/lib/drivers/shared/acp-transport.d.ts.map +1 -0
- package/lib/drivers/shared/acp-transport.js +152 -0
- package/lib/drivers/shared/acp-transport.js.map +1 -0
- package/lib/drivers/shared/artifacts.d.ts.map +1 -1
- package/lib/drivers/shared/artifacts.js +3 -2
- package/lib/drivers/shared/artifacts.js.map +1 -1
- package/lib/drivers/shared/experiment-behavior.d.ts +13 -0
- package/lib/drivers/shared/experiment-behavior.d.ts.map +1 -0
- package/lib/drivers/shared/experiment-behavior.js +200 -0
- package/lib/drivers/shared/experiment-behavior.js.map +1 -0
- package/lib/drivers/shared/experiment-policy.d.ts +4 -0
- package/lib/drivers/shared/experiment-policy.d.ts.map +1 -0
- package/lib/drivers/shared/experiment-policy.js +144 -0
- package/lib/drivers/shared/experiment-policy.js.map +1 -0
- package/lib/drivers/shared/skills.d.ts +3 -0
- package/lib/drivers/shared/skills.d.ts.map +1 -0
- package/lib/drivers/shared/skills.js +73 -0
- package/lib/drivers/shared/skills.js.map +1 -0
- package/lib/drivers/subprocess/index.d.ts +39 -4
- package/lib/drivers/subprocess/index.d.ts.map +1 -1
- package/lib/drivers/subprocess/index.js +56 -12
- package/lib/drivers/subprocess/index.js.map +1 -1
- package/lib/index.d.ts +24 -8
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +20 -5
- package/lib/index.js.map +1 -1
- package/lib/optimization/reflective.d.ts +3 -1
- package/lib/optimization/reflective.d.ts.map +1 -1
- package/lib/optimization/reflective.js +3 -2
- package/lib/optimization/reflective.js.map +1 -1
- package/lib/orchestrator/annotation-loader.d.ts +6 -2
- package/lib/orchestrator/annotation-loader.d.ts.map +1 -1
- package/lib/orchestrator/annotation-loader.js +8 -0
- package/lib/orchestrator/annotation-loader.js.map +1 -1
- package/lib/orchestrator/annotation-store.d.ts.map +1 -1
- package/lib/orchestrator/annotation-store.js +16 -2
- package/lib/orchestrator/annotation-store.js.map +1 -1
- package/lib/orchestrator/artifact-origin.d.ts +3 -0
- package/lib/orchestrator/artifact-origin.d.ts.map +1 -0
- package/lib/orchestrator/artifact-origin.js +40 -0
- package/lib/orchestrator/artifact-origin.js.map +1 -0
- package/lib/orchestrator/campaign-lifecycle.d.ts +1 -0
- package/lib/orchestrator/campaign-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/campaign-lifecycle.js +4 -1
- package/lib/orchestrator/campaign-lifecycle.js.map +1 -1
- package/lib/orchestrator/candidates.d.ts.map +1 -1
- package/lib/orchestrator/candidates.js +3 -2
- package/lib/orchestrator/candidates.js.map +1 -1
- package/lib/orchestrator/compare.d.ts +23 -6
- package/lib/orchestrator/compare.d.ts.map +1 -1
- package/lib/orchestrator/compare.js +45 -12
- package/lib/orchestrator/compare.js.map +1 -1
- package/lib/orchestrator/comparison-identity.d.ts.map +1 -1
- package/lib/orchestrator/comparison-identity.js +2 -0
- package/lib/orchestrator/comparison-identity.js.map +1 -1
- package/lib/orchestrator/config.d.ts +180 -1
- package/lib/orchestrator/config.d.ts.map +1 -1
- package/lib/orchestrator/config.js +21 -2
- package/lib/orchestrator/config.js.map +1 -1
- package/lib/orchestrator/discover.d.ts +1 -0
- package/lib/orchestrator/discover.d.ts.map +1 -1
- package/lib/orchestrator/discover.js +7 -1
- package/lib/orchestrator/discover.js.map +1 -1
- package/lib/orchestrator/doctor.d.ts +1 -0
- package/lib/orchestrator/doctor.d.ts.map +1 -1
- package/lib/orchestrator/doctor.js +134 -69
- package/lib/orchestrator/doctor.js.map +1 -1
- package/lib/orchestrator/driver-capabilities.d.ts +4 -0
- package/lib/orchestrator/driver-capabilities.d.ts.map +1 -0
- package/lib/orchestrator/driver-capabilities.js +13 -0
- package/lib/orchestrator/driver-capabilities.js.map +1 -0
- package/lib/orchestrator/driver-identity.d.ts +5 -0
- package/lib/orchestrator/driver-identity.d.ts.map +1 -0
- package/lib/orchestrator/driver-identity.js +51 -0
- package/lib/orchestrator/driver-identity.js.map +1 -0
- package/lib/orchestrator/experiment-context.d.ts +51 -3
- package/lib/orchestrator/experiment-context.d.ts.map +1 -1
- package/lib/orchestrator/experiment-context.js +2 -1
- package/lib/orchestrator/experiment-context.js.map +1 -1
- package/lib/orchestrator/experiment-contracts.d.ts +31 -1
- package/lib/orchestrator/experiment-contracts.d.ts.map +1 -1
- package/lib/orchestrator/experiment-corpus.d.ts +2 -1
- package/lib/orchestrator/experiment-corpus.d.ts.map +1 -1
- package/lib/orchestrator/experiment-corpus.js +28 -22
- package/lib/orchestrator/experiment-corpus.js.map +1 -1
- package/lib/orchestrator/experiment-effects.d.ts +33 -0
- package/lib/orchestrator/experiment-effects.d.ts.map +1 -0
- package/lib/orchestrator/experiment-effects.js +46 -0
- package/lib/orchestrator/experiment-effects.js.map +1 -0
- package/lib/orchestrator/experiment-evaluation.d.ts.map +1 -1
- package/lib/orchestrator/experiment-evaluation.js +70 -5
- package/lib/orchestrator/experiment-evaluation.js.map +1 -1
- package/lib/orchestrator/experiment-identity.d.ts +3 -0
- package/lib/orchestrator/experiment-identity.d.ts.map +1 -1
- package/lib/orchestrator/experiment-identity.js +22 -33
- package/lib/orchestrator/experiment-identity.js.map +1 -1
- package/lib/orchestrator/experiment-loader.d.ts +8 -3
- package/lib/orchestrator/experiment-loader.d.ts.map +1 -1
- package/lib/orchestrator/experiment-preflight.d.ts +3 -0
- package/lib/orchestrator/experiment-preflight.d.ts.map +1 -0
- package/lib/orchestrator/experiment-preflight.js +21 -0
- package/lib/orchestrator/experiment-preflight.js.map +1 -0
- package/lib/orchestrator/experiment-report.d.ts +91 -1
- package/lib/orchestrator/experiment-report.d.ts.map +1 -1
- package/lib/orchestrator/experiment-report.js +9 -1
- package/lib/orchestrator/experiment-report.js.map +1 -1
- package/lib/orchestrator/experiment-runs.d.ts +63 -2
- package/lib/orchestrator/experiment-runs.d.ts.map +1 -1
- package/lib/orchestrator/experiment-runs.js +13 -5
- package/lib/orchestrator/experiment-runs.js.map +1 -1
- package/lib/orchestrator/experiment-runtime-identity.d.ts +0 -16
- package/lib/orchestrator/experiment-runtime-identity.d.ts.map +1 -1
- package/lib/orchestrator/experiment-runtime-identity.js +5 -220
- package/lib/orchestrator/experiment-runtime-identity.js.map +1 -1
- package/lib/orchestrator/experiment-selection.d.ts.map +1 -1
- package/lib/orchestrator/experiment-selection.js +151 -43
- package/lib/orchestrator/experiment-selection.js.map +1 -1
- package/lib/orchestrator/experiment.d.ts +3 -3
- package/lib/orchestrator/experiment.d.ts.map +1 -1
- package/lib/orchestrator/experiment.js +26 -21
- package/lib/orchestrator/experiment.js.map +1 -1
- package/lib/orchestrator/fixture-identity.d.ts +1 -0
- package/lib/orchestrator/fixture-identity.d.ts.map +1 -1
- package/lib/orchestrator/fixture-identity.js +6 -1
- package/lib/orchestrator/fixture-identity.js.map +1 -1
- package/lib/orchestrator/fs-read.d.ts +1 -6
- package/lib/orchestrator/fs-read.d.ts.map +1 -1
- package/lib/orchestrator/fs-read.js +2 -32
- package/lib/orchestrator/fs-read.js.map +1 -1
- package/lib/orchestrator/grader-experiment.d.ts +23 -5
- package/lib/orchestrator/grader-experiment.d.ts.map +1 -1
- package/lib/orchestrator/grader-experiment.js +54 -9
- package/lib/orchestrator/grader-experiment.js.map +1 -1
- package/lib/orchestrator/grading.d.ts +1 -0
- package/lib/orchestrator/grading.d.ts.map +1 -1
- package/lib/orchestrator/grading.js +41 -33
- package/lib/orchestrator/grading.js.map +1 -1
- package/lib/orchestrator/harness-catalog-drift.d.ts +22 -0
- package/lib/orchestrator/harness-catalog-drift.d.ts.map +1 -0
- package/lib/orchestrator/harness-catalog-drift.js +90 -0
- package/lib/orchestrator/harness-catalog-drift.js.map +1 -0
- package/lib/orchestrator/harness-registry.d.ts +4 -0
- package/lib/orchestrator/harness-registry.d.ts.map +1 -0
- package/lib/orchestrator/harness-registry.js +5 -0
- package/lib/orchestrator/harness-registry.js.map +1 -0
- package/lib/orchestrator/index.d.ts +1 -1
- package/lib/orchestrator/index.d.ts.map +1 -1
- package/lib/orchestrator/index.js +1 -1
- package/lib/orchestrator/index.js.map +1 -1
- package/lib/orchestrator/list-runs.d.ts +8 -1
- package/lib/orchestrator/list-runs.d.ts.map +1 -1
- package/lib/orchestrator/list-runs.js +83 -18
- package/lib/orchestrator/list-runs.js.map +1 -1
- package/lib/orchestrator/optimization-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/optimization-lifecycle.js +3 -1
- package/lib/orchestrator/optimization-lifecycle.js.map +1 -1
- package/lib/orchestrator/orchestrator.d.ts +17 -2
- package/lib/orchestrator/orchestrator.d.ts.map +1 -1
- package/lib/orchestrator/orchestrator.js +55 -177
- package/lib/orchestrator/orchestrator.js.map +1 -1
- package/lib/orchestrator/paired-effects.d.ts +34 -0
- package/lib/orchestrator/paired-effects.d.ts.map +1 -0
- package/lib/orchestrator/paired-effects.js +164 -0
- package/lib/orchestrator/paired-effects.js.map +1 -0
- package/lib/orchestrator/profile.d.ts +4 -0
- package/lib/orchestrator/profile.d.ts.map +1 -0
- package/lib/orchestrator/profile.js +10 -0
- package/lib/orchestrator/profile.js.map +1 -0
- package/lib/orchestrator/provenance.d.ts +5 -1
- package/lib/orchestrator/provenance.d.ts.map +1 -1
- package/lib/orchestrator/provenance.js +16 -3
- package/lib/orchestrator/provenance.js.map +1 -1
- package/lib/orchestrator/regrade.d.ts +4 -2
- package/lib/orchestrator/regrade.d.ts.map +1 -1
- package/lib/orchestrator/rubric-loader.js +1 -1
- package/lib/orchestrator/rubric-loader.js.map +1 -1
- package/lib/orchestrator/run-dir.d.ts +2 -0
- package/lib/orchestrator/run-dir.d.ts.map +1 -1
- package/lib/orchestrator/run-dir.js +1 -1
- package/lib/orchestrator/run-dir.js.map +1 -1
- package/lib/orchestrator/run-execution.d.ts +3 -0
- package/lib/orchestrator/run-execution.d.ts.map +1 -1
- package/lib/orchestrator/run-execution.js +64 -10
- package/lib/orchestrator/run-execution.js.map +1 -1
- package/lib/orchestrator/run-lifecycle.d.ts +1 -0
- package/lib/orchestrator/run-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/run-lifecycle.js +3 -2
- package/lib/orchestrator/run-lifecycle.js.map +1 -1
- package/lib/orchestrator/run-workspace.d.ts +10 -0
- package/lib/orchestrator/run-workspace.d.ts.map +1 -0
- package/lib/orchestrator/run-workspace.js +58 -0
- package/lib/orchestrator/run-workspace.js.map +1 -0
- package/lib/orchestrator/suite-compare.d.ts +37 -0
- package/lib/orchestrator/suite-compare.d.ts.map +1 -1
- package/lib/orchestrator/suite-compare.js +44 -22
- package/lib/orchestrator/suite-compare.js.map +1 -1
- package/lib/orchestrator/suite-runs.d.ts +6 -1
- package/lib/orchestrator/suite-runs.d.ts.map +1 -1
- package/lib/orchestrator/suite-runs.js +14 -2
- package/lib/orchestrator/suite-runs.js.map +1 -1
- package/lib/orchestrator/suite-summary.d.ts +79 -0
- package/lib/orchestrator/suite-summary.d.ts.map +1 -1
- package/lib/orchestrator/suite-summary.js +67 -14
- package/lib/orchestrator/suite-summary.js.map +1 -1
- package/lib/previewer/artifacts.d.ts +25 -0
- package/lib/previewer/artifacts.d.ts.map +1 -0
- package/lib/previewer/artifacts.js +180 -0
- package/lib/previewer/artifacts.js.map +1 -0
- package/lib/previewer/server.d.ts +111 -0
- package/lib/previewer/server.d.ts.map +1 -0
- package/lib/previewer/server.js +559 -0
- package/lib/previewer/server.js.map +1 -0
- package/package.json +4 -2
- package/skills/lux-answerer/SKILL.md +2 -2
- package/src/answerers/claude-code/index.ts +6 -5
- package/src/answerers/persona/index.ts +75 -34
- package/src/answerers/terminal/index.ts +7 -11
- package/src/assertions/authoring.ts +2 -0
- package/src/assertions/core/command-exits-zero.ts +82 -17
- package/src/assertions/core/event-checks.ts +64 -3
- package/src/assertions/core/index.ts +2 -0
- package/src/assertions/core/resource-checks.ts +38 -5
- package/src/assertions/core/safe-regex.ts +16 -6
- package/src/assertions/rubric/evidence.ts +85 -0
- package/src/assertions/rubric/index.ts +63 -46
- package/src/assertions/rubric/internal.ts +256 -41
- package/src/authoring.ts +346 -2
- package/src/cli/bin.ts +2 -12
- package/src/cli/command-runtime.ts +20 -9
- package/src/cli/doctor.ts +17 -0
- package/src/cli/harness-plan.ts +123 -0
- package/src/cli/init-templates.ts +238 -0
- package/src/cli/init.ts +53 -184
- package/src/cli/output-schemas.ts +109 -0
- package/src/cli/program.ts +697 -730
- package/src/cli/render/format.ts +1 -1
- package/src/cli/render/reporter.ts +36 -8
- package/src/cli/run-options.ts +131 -25
- package/src/cli/view.ts +129 -0
- package/src/container/driver.ts +213 -0
- package/src/container/paths.ts +29 -0
- package/src/container/protocol.ts +48 -0
- package/src/container/resources.ts +165 -0
- package/src/container/worker.ts +107 -0
- package/src/core/action-events.ts +59 -0
- package/src/core/agent-activity.ts +236 -0
- package/src/core/agent-environment.ts +64 -0
- package/src/core/agent-events.ts +17 -0
- package/src/core/annotation.ts +2 -1
- package/src/core/answerer.ts +9 -0
- package/src/core/artifact-evidence.ts +40 -5
- package/src/core/assertion.ts +8 -2
- package/src/core/case-defaults.ts +65 -0
- package/src/core/case.ts +79 -8
- package/src/core/command-verification.ts +74 -0
- package/src/core/driver-execution.ts +84 -0
- package/src/core/driver-metrics.ts +51 -0
- package/src/core/driver.ts +76 -0
- package/src/core/duration.ts +52 -0
- package/src/core/environment.ts +22 -0
- package/src/core/evaluation-clusters.ts +35 -0
- package/src/core/events.ts +13 -2
- package/src/core/experiment.ts +71 -25
- package/src/core/file-tree.ts +35 -0
- package/src/core/global-id.ts +26 -0
- package/src/core/harness-catalog.ts +100 -0
- package/src/core/harness-catalogs/antigravity.ts +24 -0
- package/src/core/harness-catalogs/claude-code.ts +25 -0
- package/src/core/harness-catalogs/codex.ts +27 -0
- package/src/core/harness-catalogs/copilot.ts +46 -0
- package/src/core/harness-catalogs/cursor.ts +13 -0
- package/src/core/harness-catalogs/grok-build.ts +19 -0
- package/src/core/harness-catalogs/index.ts +31 -0
- package/src/core/harness-matrix.ts +316 -0
- package/src/core/index.ts +12 -0
- package/src/core/lifecycle-fixtures.ts +4 -2
- package/src/core/model-cli.ts +60 -26
- package/src/core/platform-process.ts +65 -16
- package/src/core/reference-defaults.ts +47 -0
- package/src/core/run.ts +31 -0
- package/src/core/usage.ts +8 -0
- package/src/drivers/antigravity/README.md +171 -0
- package/src/drivers/antigravity/artifacts.ts +37 -0
- package/src/drivers/antigravity/config.ts +92 -0
- package/src/drivers/antigravity/events.ts +290 -0
- package/src/drivers/antigravity/index.ts +132 -0
- package/src/drivers/antigravity/runtime.ts +94 -0
- package/src/drivers/claude-code/deferred-process.ts +118 -0
- package/src/drivers/claude-code/index.ts +227 -281
- package/src/drivers/claude-code/isolation.ts +228 -0
- package/src/drivers/claude-code/parse-events.ts +98 -12
- package/src/drivers/codex/app-events.ts +126 -16
- package/src/drivers/codex/config.ts +59 -8
- package/src/drivers/codex/exec-events.ts +258 -0
- package/src/drivers/codex/index.ts +146 -312
- package/src/drivers/copilot/README.md +60 -0
- package/src/drivers/copilot/config.ts +61 -0
- package/src/drivers/copilot/index.ts +310 -0
- package/src/drivers/cursor/README.md +66 -0
- package/src/drivers/cursor/config.ts +31 -0
- package/src/drivers/cursor/index.ts +326 -0
- package/src/drivers/cursor/interaction.ts +74 -0
- package/src/drivers/grok-build/README.md +112 -0
- package/src/drivers/grok-build/config.ts +43 -0
- package/src/drivers/grok-build/index.ts +331 -0
- package/src/drivers/mcp/index.ts +25 -11
- package/src/drivers/shared/acp-events.ts +94 -0
- package/src/drivers/shared/acp-interaction.ts +27 -0
- package/src/drivers/shared/acp-session.ts +40 -0
- package/src/drivers/shared/acp-transport.ts +187 -0
- package/src/drivers/shared/artifacts.ts +6 -2
- package/src/drivers/shared/experiment-behavior.ts +217 -0
- package/src/drivers/shared/experiment-policy.ts +196 -0
- package/src/drivers/shared/skills.ts +74 -0
- package/src/drivers/subprocess/index.ts +55 -12
- package/src/index.ts +117 -6
- package/src/optimization/reflective.ts +3 -2
- package/src/orchestrator/annotation-loader.ts +10 -0
- package/src/orchestrator/annotation-store.ts +24 -3
- package/src/orchestrator/artifact-origin.ts +50 -0
- package/src/orchestrator/campaign-lifecycle.ts +5 -1
- package/src/orchestrator/candidates.ts +3 -2
- package/src/orchestrator/compare.ts +62 -13
- package/src/orchestrator/comparison-identity.ts +2 -0
- package/src/orchestrator/config.ts +23 -1
- package/src/orchestrator/discover.ts +8 -1
- package/src/orchestrator/doctor.ts +211 -65
- package/src/orchestrator/driver-capabilities.ts +21 -0
- package/src/orchestrator/driver-identity.ts +69 -0
- package/src/orchestrator/experiment-context.ts +5 -3
- package/src/orchestrator/experiment-corpus.ts +58 -37
- package/src/orchestrator/experiment-effects.ts +63 -0
- package/src/orchestrator/experiment-evaluation.ts +88 -10
- package/src/orchestrator/experiment-identity.ts +57 -48
- package/src/orchestrator/experiment-preflight.ts +27 -0
- package/src/orchestrator/experiment-report.ts +21 -1
- package/src/orchestrator/experiment-runs.ts +11 -4
- package/src/orchestrator/experiment-runtime-identity.ts +5 -243
- package/src/orchestrator/experiment-selection.ts +178 -18
- package/src/orchestrator/experiment.ts +29 -29
- package/src/orchestrator/fixture-identity.ts +9 -1
- package/src/orchestrator/fs-read.ts +2 -32
- package/src/orchestrator/grader-experiment.ts +74 -13
- package/src/orchestrator/grading.ts +60 -31
- package/src/orchestrator/harness-catalog-drift.ts +132 -0
- package/src/orchestrator/harness-registry.ts +12 -0
- package/src/orchestrator/index.ts +1 -0
- package/src/orchestrator/list-runs.ts +102 -18
- package/src/orchestrator/optimization-lifecycle.ts +4 -1
- package/src/orchestrator/orchestrator.ts +105 -224
- package/src/orchestrator/paired-effects.ts +214 -0
- package/src/orchestrator/profile.ts +24 -0
- package/src/orchestrator/provenance.ts +23 -3
- package/src/orchestrator/rubric-loader.ts +1 -1
- package/src/orchestrator/run-dir.ts +8 -1
- package/src/orchestrator/run-execution.ts +75 -10
- package/src/orchestrator/run-lifecycle.ts +4 -2
- package/src/orchestrator/run-workspace.ts +62 -0
- package/src/orchestrator/suite-compare.ts +47 -23
- package/src/orchestrator/suite-runs.ts +13 -2
- package/src/orchestrator/suite-summary.ts +129 -15
- package/src/previewer/artifacts.ts +221 -0
- package/src/previewer/server.ts +789 -0
- package/viewer/app.css +2111 -0
- package/viewer/app.js +627 -0
- package/viewer/artifact-view.js +48 -0
- package/viewer/charts.js +98 -0
- package/viewer/detail.js +1266 -0
- package/viewer/format.js +129 -0
- package/viewer/index.html +151 -0
- package/lib/cli/skills.d.ts +0 -38
- package/lib/cli/skills.d.ts.map +0 -1
- package/lib/cli/skills.js +0 -84
- package/lib/cli/skills.js.map +0 -1
- package/lib/drivers/shared/secure-copy.d.ts.map +0 -1
- package/lib/drivers/shared/secure-copy.js.map +0 -1
- package/skills/lux/SKILL.md +0 -89
- package/skills/lux/references/cli.md +0 -125
- package/skills/lux/references/eval-authoring.md +0 -257
- package/src/cli/skills.ts +0 -129
- /package/lib/{drivers/shared → core}/secure-copy.d.ts +0 -0
- /package/lib/{drivers/shared → core}/secure-copy.js +0 -0
- /package/src/{drivers/shared → core}/secure-copy.ts +0 -0
|
@@ -2,6 +2,7 @@ import { basename } from "node:path";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { valueHash } from "../core/index.js";
|
|
4
4
|
import { deriveExperimentSelection, rankCandidates } from "./experiment.js";
|
|
5
|
+
import { ExperimentEffectsSchema, experimentEffects } from "./experiment-effects.js";
|
|
5
6
|
import {
|
|
6
7
|
type ExperimentRun,
|
|
7
8
|
ExperimentRunSchema,
|
|
@@ -24,6 +25,7 @@ export const ExperimentDecisionReportSchema = z
|
|
|
24
25
|
status: z.enum(["running", "passed", "failed", "aborted"]),
|
|
25
26
|
outcome: z.enum(["promote", "retain", "reject", "error", "incomplete"]),
|
|
26
27
|
error: z.string().nullable(),
|
|
28
|
+
effects: z.exactOptional(ExperimentEffectsSchema),
|
|
27
29
|
candidateAndAccountingVerified: z.boolean(),
|
|
28
30
|
championCandidateId: z.string().nullable(),
|
|
29
31
|
ranking: z.array(z.string()),
|
|
@@ -39,6 +41,7 @@ export const ExperimentDecisionReportSchema = z
|
|
|
39
41
|
z
|
|
40
42
|
.object({
|
|
41
43
|
metric: z.string(),
|
|
44
|
+
relativeTo: z.exactOptional(z.literal("baseline")),
|
|
42
45
|
profile: z.string().nullable(),
|
|
43
46
|
split: ExperimentReportSplitSchema,
|
|
44
47
|
passed: z.boolean(),
|
|
@@ -596,6 +599,7 @@ const projectExperimentDecisionReport = (
|
|
|
596
599
|
evaluationKind: experiment.evaluationKind,
|
|
597
600
|
status: experiment.status,
|
|
598
601
|
error: experiment.errorMessage ?? null,
|
|
602
|
+
effects: experimentEffects(experiment),
|
|
599
603
|
candidateAndAccountingVerified,
|
|
600
604
|
outcome: reportOutcome(experiment, championId),
|
|
601
605
|
championCandidateId: championId,
|
|
@@ -610,6 +614,7 @@ const projectExperimentDecisionReport = (
|
|
|
610
614
|
.filter((constraint) => constraint.candidateId === targetId)
|
|
611
615
|
.map((constraint) => ({
|
|
612
616
|
metric: constraint.metric,
|
|
617
|
+
...(constraint.relativeTo ? { relativeTo: constraint.relativeTo } : {}),
|
|
613
618
|
profile: constraint.profile ?? null,
|
|
614
619
|
split: constraint.split,
|
|
615
620
|
passed: constraint.passed,
|
|
@@ -733,7 +738,7 @@ export const formatExperimentDecisionMarkdown = (report: ExperimentDecisionRepor
|
|
|
733
738
|
"| --- | --- | --- | --- | ---: | --- | --- |",
|
|
734
739
|
...report.gates.map(
|
|
735
740
|
(gate) =>
|
|
736
|
-
`| ${gate.passed ? "PASS" : "FAIL"} | ${markdown(gate.metric)} | ${markdown(gate.profile ?? "all")} | ${gate.split} | ${gate.values.map(concise).join(", ") || "—"} | ${markdown(gate.interval ?? "—")} | ${markdown(gate.note ?? "—")} |`,
|
|
741
|
+
`| ${gate.passed ? "PASS" : "FAIL"} | ${markdown(gate.metric)}${gate.relativeTo ? " Δ baseline" : ""} | ${markdown(gate.profile ?? "all")} | ${gate.split} | ${gate.values.map(concise).join(", ") || "—"} | ${markdown(gate.interval ?? "—")} | ${markdown(gate.note ?? "—")} |`,
|
|
737
742
|
),
|
|
738
743
|
);
|
|
739
744
|
}
|
|
@@ -763,6 +768,21 @@ export const formatExperimentDecisionMarkdown = (report: ExperimentDecisionRepor
|
|
|
763
768
|
),
|
|
764
769
|
);
|
|
765
770
|
}
|
|
771
|
+
if (report.effects?.length) {
|
|
772
|
+
lines.push(
|
|
773
|
+
"",
|
|
774
|
+
"## Paired case effects",
|
|
775
|
+
"",
|
|
776
|
+
"Differences are candidate minus baseline; repetitions are averaged within cases and authored clusters receive equal weight.",
|
|
777
|
+
"",
|
|
778
|
+
"| Candidate | Profile | Split | Metric | Mean difference | Cases | Clusters | Confidence | Note |",
|
|
779
|
+
"| --- | --- | --- | --- | ---: | ---: | ---: | --- | --- |",
|
|
780
|
+
...report.effects.map(
|
|
781
|
+
(effect) =>
|
|
782
|
+
`| ${markdown(effect.candidateId)} | ${markdown(effect.profileId)} | ${effect.split} | ${markdown(effect.metric)} | ${effect.meanDelta === null ? "—" : signed(effect.meanDelta)} | ${effect.caseCount ?? effect.caseIds.length} | ${effect.n} | ${markdown(intervalText(effect.interval ?? undefined) ?? "—")} | ${markdown(effect.note ?? "—")} |`,
|
|
783
|
+
),
|
|
784
|
+
);
|
|
785
|
+
}
|
|
766
786
|
lines.push(
|
|
767
787
|
"",
|
|
768
788
|
"## Source and spend",
|
|
@@ -86,6 +86,7 @@ export const ExperimentSelectionSchema = z.object({
|
|
|
86
86
|
z.object({
|
|
87
87
|
candidateId: CandidateIdSchema,
|
|
88
88
|
metric: z.string(),
|
|
89
|
+
relativeTo: z.exactOptional(z.literal("baseline")),
|
|
89
90
|
profile: z.exactOptional(z.string()),
|
|
90
91
|
split: z.enum(["train", "validation", "test"]),
|
|
91
92
|
values: z.array(z.number()),
|
|
@@ -738,6 +739,7 @@ export const resumeExperimentRun = async (path: string): Promise<OpenedExperimen
|
|
|
738
739
|
|
|
739
740
|
export const listExperimentRuns = async (
|
|
740
741
|
runsRoot: string,
|
|
742
|
+
options: { onReadError?: (path: string, error: unknown) => void } = {},
|
|
741
743
|
): Promise<Array<ExperimentRun & { experimentDir: string }>> => {
|
|
742
744
|
const root = join(resolve(runsRoot), EXPERIMENTS_DIR);
|
|
743
745
|
if (!existsSync(root)) return [];
|
|
@@ -745,10 +747,15 @@ export const listExperimentRuns = async (
|
|
|
745
747
|
.filter((entry) => entry.isDirectory())
|
|
746
748
|
.map((entry) => join(root, entry.name));
|
|
747
749
|
const runs = await Promise.all(
|
|
748
|
-
directories.map(async (experimentDir) =>
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
750
|
+
directories.map(async (experimentDir) => {
|
|
751
|
+
try {
|
|
752
|
+
return { experimentDir, experiment: await loadExperimentRun(experimentDir) };
|
|
753
|
+
} catch (error) {
|
|
754
|
+
if (!options.onReadError) throw error;
|
|
755
|
+
options.onReadError(experimentDir, error);
|
|
756
|
+
return { experimentDir, experiment: null };
|
|
757
|
+
}
|
|
758
|
+
}),
|
|
752
759
|
);
|
|
753
760
|
return runs
|
|
754
761
|
.flatMap(({ experimentDir, experiment }) =>
|
|
@@ -1,61 +1,14 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { access, constants, lstat, open,
|
|
3
|
-
import { homedir } from "node:os";
|
|
2
|
+
import { access, constants, lstat, open, realpath } from "node:fs/promises";
|
|
4
3
|
import { delimiter, isAbsolute, join, resolve } from "node:path";
|
|
5
4
|
import { z } from "zod";
|
|
6
|
-
import {
|
|
7
|
-
import { walkAuthoredFiles } from "./fs-read.js";
|
|
8
|
-
import { boundExperimentDriverConfig } from "./orchestrator.js";
|
|
5
|
+
import { discoverCliVersion, valueHash } from "../core/index.js";
|
|
9
6
|
|
|
10
7
|
export { LUX_VERSION } from "./package-version.js";
|
|
11
8
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
const ClaudeInstalledPluginRecordSchema = z.looseObject({
|
|
16
|
-
installPath: z.string(),
|
|
17
|
-
});
|
|
18
|
-
const ClaudeInstalledPluginsFileSchema = z.looseObject({
|
|
19
|
-
plugins: z.record(z.string(), z.array(ClaudeInstalledPluginRecordSchema)),
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
export const referencedCli = (
|
|
23
|
-
reference: unknown,
|
|
24
|
-
): { name: string; command: string } | undefined => {
|
|
25
|
-
let name: string | undefined;
|
|
26
|
-
if (typeof reference === "string") {
|
|
27
|
-
name = reference;
|
|
28
|
-
} else if (
|
|
29
|
-
typeof reference === "object" &&
|
|
30
|
-
reference !== null &&
|
|
31
|
-
typeof (reference as { name?: unknown }).name === "string"
|
|
32
|
-
) {
|
|
33
|
-
name = (reference as { name: string }).name;
|
|
34
|
-
}
|
|
35
|
-
const config =
|
|
36
|
-
typeof reference === "object" && reference !== null
|
|
37
|
-
? (reference as { config?: unknown }).config
|
|
38
|
-
: undefined;
|
|
39
|
-
if (name === "subprocess") {
|
|
40
|
-
if (
|
|
41
|
-
typeof config !== "object" ||
|
|
42
|
-
config === null ||
|
|
43
|
-
typeof (config as { command?: unknown }).command !== "string"
|
|
44
|
-
) {
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
return { name, command: (config as { command: string }).command };
|
|
48
|
-
}
|
|
49
|
-
if (name !== "claude-code" && name !== "codex") return undefined;
|
|
50
|
-
let command = name === "codex" ? "codex" : "claude";
|
|
51
|
-
if (
|
|
52
|
-
typeof config === "object" &&
|
|
53
|
-
config !== null &&
|
|
54
|
-
typeof (config as { command?: unknown }).command === "string"
|
|
55
|
-
) {
|
|
56
|
-
command = (config as { command: string }).command;
|
|
57
|
-
}
|
|
58
|
-
return { name, command };
|
|
9
|
+
const driverConfigRecord = (reference: unknown): Record<string, unknown> => {
|
|
10
|
+
const config = (reference as { config?: unknown } | null)?.config;
|
|
11
|
+
return config && typeof config === "object" ? (config as Record<string, unknown>) : {};
|
|
59
12
|
};
|
|
60
13
|
|
|
61
14
|
export const referencedAnswererCli = (
|
|
@@ -261,197 +214,6 @@ export const cliIdentity = async (command: string, baseRoot: string): Promise<Cl
|
|
|
261
214
|
});
|
|
262
215
|
};
|
|
263
216
|
|
|
264
|
-
const optionalRegularFileHash = async (path: string): Promise<string | null> => {
|
|
265
|
-
try {
|
|
266
|
-
const info = await lstat(path);
|
|
267
|
-
if (info.isSymbolicLink() || !info.isFile()) {
|
|
268
|
-
throw new Error(`behavior-affecting settings must be a regular file: ${path}`);
|
|
269
|
-
}
|
|
270
|
-
return contentHash(await readFile(path));
|
|
271
|
-
} catch (error) {
|
|
272
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
|
|
273
|
-
throw error;
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
const driverConfigRecord = (driver: unknown): Record<string, unknown> => {
|
|
278
|
-
if (!driver || typeof driver !== "object") return {};
|
|
279
|
-
const config = (driver as { config?: unknown }).config;
|
|
280
|
-
return config && typeof config === "object" ? (config as Record<string, unknown>) : {};
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
export const claudeConfigRoot = (driver: unknown): string => {
|
|
284
|
-
const config = driverConfigRecord(driver);
|
|
285
|
-
const env =
|
|
286
|
-
config.env && typeof config.env === "object"
|
|
287
|
-
? (config.env as Record<string, unknown>)
|
|
288
|
-
: undefined;
|
|
289
|
-
const configured = env?.CLAUDE_CONFIG_DIR;
|
|
290
|
-
const root =
|
|
291
|
-
typeof configured === "string"
|
|
292
|
-
? configured
|
|
293
|
-
: (process.env.CLAUDE_CONFIG_DIR ?? join(homedir(), ".claude"));
|
|
294
|
-
if (!isAbsolute(root)) {
|
|
295
|
-
throw new Error("CLAUDE_CONFIG_DIR must be absolute for reproducible experiment identity");
|
|
296
|
-
}
|
|
297
|
-
return resolve(root);
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
const hashBehaviorDirectory = async (
|
|
301
|
-
root: string,
|
|
302
|
-
label: string,
|
|
303
|
-
): Promise<Array<{ path: string; hash: string }>> => {
|
|
304
|
-
try {
|
|
305
|
-
const info = await lstat(root);
|
|
306
|
-
if (info.isSymbolicLink() || !info.isDirectory()) {
|
|
307
|
-
throw new Error(`behavior-affecting Claude source must be a real directory: ${root}`);
|
|
308
|
-
}
|
|
309
|
-
} catch (error) {
|
|
310
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
|
|
311
|
-
throw error;
|
|
312
|
-
}
|
|
313
|
-
const paths = await walkAuthoredFiles(root);
|
|
314
|
-
if (paths.length > 5_000) {
|
|
315
|
-
throw new Error(`behavior-affecting Claude source '${label}' exceeds 5000 files`);
|
|
316
|
-
}
|
|
317
|
-
let bytes = 0;
|
|
318
|
-
const hashes: Array<{ path: string; hash: string }> = [];
|
|
319
|
-
for (const path of paths) {
|
|
320
|
-
const content = await readFile(join(root, path));
|
|
321
|
-
bytes += content.length;
|
|
322
|
-
if (bytes > 256 * 1024 * 1024) {
|
|
323
|
-
throw new Error(`behavior-affecting Claude source '${label}' exceeds 256 MiB`);
|
|
324
|
-
}
|
|
325
|
-
hashes.push({ path: `${label}/${path}`, hash: contentHash(content) });
|
|
326
|
-
}
|
|
327
|
-
return hashes;
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* Hash every intentionally loaded user behavior source without persisting its
|
|
332
|
-
* contents. This covers user instructions/rules/output styles and the exact
|
|
333
|
-
* installed contents of plugins enabled by settings.json.
|
|
334
|
-
*/
|
|
335
|
-
export const claudeUserBehaviorHash = async (configRoot: string): Promise<string | null> => {
|
|
336
|
-
const settingsPath = join(configRoot, "settings.json");
|
|
337
|
-
const settingsHash = await optionalRegularFileHash(settingsPath);
|
|
338
|
-
const sources: Array<{ path: string; hash: string }> = [];
|
|
339
|
-
if (settingsHash) sources.push({ path: "settings.json", hash: settingsHash });
|
|
340
|
-
const claudeMdHash = await optionalRegularFileHash(join(configRoot, "CLAUDE.md"));
|
|
341
|
-
if (claudeMdHash) sources.push({ path: "CLAUDE.md", hash: claudeMdHash });
|
|
342
|
-
for (const directory of ["rules", "output-styles", "agents", "commands", "skills"]) {
|
|
343
|
-
sources.push(...(await hashBehaviorDirectory(join(configRoot, directory), directory)));
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
let settings: unknown;
|
|
347
|
-
try {
|
|
348
|
-
const contents = await readFile(settingsPath, "utf8");
|
|
349
|
-
try {
|
|
350
|
-
settings = JSON.parse(contents);
|
|
351
|
-
} catch {
|
|
352
|
-
throw new Error("Claude settings.json contains invalid JSON");
|
|
353
|
-
}
|
|
354
|
-
} catch (error) {
|
|
355
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
356
|
-
settings = undefined;
|
|
357
|
-
} else {
|
|
358
|
-
throw error;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
const parsedSettings = ClaudeSettingsFileSchema.safeParse(settings);
|
|
362
|
-
if (settings !== undefined && !parsedSettings.success) {
|
|
363
|
-
throw new Error("Claude settings.json has an invalid enabledPlugins map");
|
|
364
|
-
}
|
|
365
|
-
const enabledPlugins = parsedSettings.success ? parsedSettings.data.enabledPlugins : undefined;
|
|
366
|
-
const enabledIds = Object.entries(enabledPlugins ?? {})
|
|
367
|
-
.filter(([, value]) => value === true)
|
|
368
|
-
.map(([id]) => id)
|
|
369
|
-
.sort();
|
|
370
|
-
if (enabledIds.length > 0) {
|
|
371
|
-
const installedPath = join(configRoot, "plugins", "installed_plugins.json");
|
|
372
|
-
const installedHash = await optionalRegularFileHash(installedPath);
|
|
373
|
-
if (installedHash) {
|
|
374
|
-
sources.push({ path: "plugins/installed_plugins.json", hash: installedHash });
|
|
375
|
-
}
|
|
376
|
-
let installed: unknown;
|
|
377
|
-
try {
|
|
378
|
-
installed = JSON.parse(await readFile(installedPath, "utf8"));
|
|
379
|
-
} catch {
|
|
380
|
-
installed = undefined;
|
|
381
|
-
}
|
|
382
|
-
const parsedInstalled = ClaudeInstalledPluginsFileSchema.safeParse(installed);
|
|
383
|
-
if (!parsedInstalled.success) {
|
|
384
|
-
throw new Error("enabled Claude plugins have invalid installed metadata");
|
|
385
|
-
}
|
|
386
|
-
const plugins = parsedInstalled.data.plugins;
|
|
387
|
-
for (const id of enabledIds) {
|
|
388
|
-
const records = plugins[id];
|
|
389
|
-
if (!records || records.length === 0) {
|
|
390
|
-
throw new Error(`enabled Claude plugin '${id}' has no installed content to hash`);
|
|
391
|
-
}
|
|
392
|
-
for (const [index, record] of records.entries()) {
|
|
393
|
-
const installPath = record.installPath;
|
|
394
|
-
sources.push(
|
|
395
|
-
...(await hashBehaviorDirectory(resolve(installPath), `plugins/enabled/${id}/${index}`)),
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
return sources.length === 0 ? null : valueHash(sources);
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
export const configuredClaudeSourceHashes = async (
|
|
404
|
-
driver: unknown,
|
|
405
|
-
baseRoot: string,
|
|
406
|
-
cache: Map<string, Promise<string>> = new Map(),
|
|
407
|
-
): Promise<Array<{ kind: "plugin" | "read"; path: string; hash: string }>> => {
|
|
408
|
-
const driverCli = referencedCli(driver);
|
|
409
|
-
if (!driverCli) return [];
|
|
410
|
-
const config = driverConfigRecord(driver);
|
|
411
|
-
// This also rejects path-bearing extraArgs that would evade the source
|
|
412
|
-
// hashes below. Runtime applies the same guard before driver creation.
|
|
413
|
-
boundExperimentDriverConfig(driverCli.name, config, "identity-check");
|
|
414
|
-
const isolation =
|
|
415
|
-
config.isolation && typeof config.isolation === "object"
|
|
416
|
-
? (config.isolation as Record<string, unknown>)
|
|
417
|
-
: undefined;
|
|
418
|
-
const configured = [
|
|
419
|
-
...(driverCli.name === "claude-code" && Array.isArray(config.pluginDirs)
|
|
420
|
-
? config.pluginDirs.map((path) => ({ kind: "plugin" as const, path }))
|
|
421
|
-
: []),
|
|
422
|
-
...(Array.isArray(config.addDirs)
|
|
423
|
-
? config.addDirs.map((path) => ({ kind: "read" as const, path }))
|
|
424
|
-
: []),
|
|
425
|
-
...(driverCli.name === "claude-code" && isolation && Array.isArray(isolation.allowRead)
|
|
426
|
-
? isolation.allowRead.map((path) => ({ kind: "read" as const, path }))
|
|
427
|
-
: []),
|
|
428
|
-
].filter(
|
|
429
|
-
(entry): entry is { kind: "plugin" | "read"; path: string } =>
|
|
430
|
-
typeof entry.path === "string" && entry.path.length > 0,
|
|
431
|
-
);
|
|
432
|
-
return Promise.all(
|
|
433
|
-
configured
|
|
434
|
-
.sort((a, b) => `${a.kind}:${a.path}`.localeCompare(`${b.kind}:${b.path}`))
|
|
435
|
-
.map(async ({ kind, path }) => {
|
|
436
|
-
const absolute = resolve(baseRoot, path);
|
|
437
|
-
const key = `${kind}:${absolute}`;
|
|
438
|
-
let hash = cache.get(key);
|
|
439
|
-
if (!hash) {
|
|
440
|
-
hash = hashBehaviorDirectory(
|
|
441
|
-
absolute,
|
|
442
|
-
`driver/${kind}/${contentHash(absolute).slice(0, 12)}`,
|
|
443
|
-
).then(valueHash);
|
|
444
|
-
cache.set(key, hash);
|
|
445
|
-
}
|
|
446
|
-
return {
|
|
447
|
-
kind,
|
|
448
|
-
path: absolute,
|
|
449
|
-
hash: await hash,
|
|
450
|
-
};
|
|
451
|
-
}),
|
|
452
|
-
);
|
|
453
|
-
};
|
|
454
|
-
|
|
455
217
|
export const runtimeCliIdentityHashForReferences = async (
|
|
456
218
|
references: readonly RuntimeCliReference[],
|
|
457
219
|
): Promise<string> =>
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
ExperimentSelectionSchema,
|
|
14
14
|
type OpenedExperimentRun,
|
|
15
15
|
} from "./experiment-runs.js";
|
|
16
|
+
import { confidenceGateIssue, type PairedEffect, pairedEffect } from "./paired-effects.js";
|
|
16
17
|
|
|
17
18
|
type ExperimentSplit = "train" | "validation" | "test";
|
|
18
19
|
|
|
@@ -103,6 +104,7 @@ const satisfiesConstraint = (
|
|
|
103
104
|
constraint: ExperimentConstraint,
|
|
104
105
|
experiment: OpenedExperimentRun["manifest"],
|
|
105
106
|
): boolean => {
|
|
107
|
+
if (constraint.relativeTo && candidate.id === "baseline") return true;
|
|
106
108
|
let profiles: (string | undefined)[];
|
|
107
109
|
if (constraint.metric === "subject.bytes" || constraint.profile) {
|
|
108
110
|
profiles = [constraint.profile];
|
|
@@ -110,6 +112,16 @@ const satisfiesConstraint = (
|
|
|
110
112
|
profiles = campaign.profiles;
|
|
111
113
|
}
|
|
112
114
|
return profiles.every((profile) => {
|
|
115
|
+
if (constraint.relativeTo) {
|
|
116
|
+
const effect = relativeConstraintEffect(candidate, constraint, profile, experiment);
|
|
117
|
+
if (effect.note || effect.meanDelta === null) return false;
|
|
118
|
+
const lower = effect.interval?.lower ?? effect.meanDelta;
|
|
119
|
+
const upper = effect.interval?.upper ?? effect.meanDelta;
|
|
120
|
+
return (
|
|
121
|
+
(constraint.min === undefined || lower >= constraint.min) &&
|
|
122
|
+
(constraint.max === undefined || upper <= constraint.max)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
113
125
|
const values = metricValues(
|
|
114
126
|
candidate,
|
|
115
127
|
constraint.metric,
|
|
@@ -135,6 +147,7 @@ const satisfiesConstraint = (
|
|
|
135
147
|
return sampleGroups.every((samples) => {
|
|
136
148
|
try {
|
|
137
149
|
const interval = bootstrapMeanConfidenceInterval(samples, constraint.confidence);
|
|
150
|
+
if (confidenceGateIssue(interval)) return false;
|
|
138
151
|
return (
|
|
139
152
|
(constraint.min === undefined || interval.lower >= constraint.min) &&
|
|
140
153
|
(constraint.max === undefined || interval.upper <= constraint.max)
|
|
@@ -156,12 +169,29 @@ const satisfiesConstraint = (
|
|
|
156
169
|
export const average = (values: readonly number[]): number =>
|
|
157
170
|
values.reduce((sum, value) => sum + value, 0) / Math.max(values.length, 1);
|
|
158
171
|
|
|
172
|
+
const relativeConstraintEffect = (
|
|
173
|
+
candidate: ExperimentDecisionCandidate,
|
|
174
|
+
constraint: ExperimentConstraint,
|
|
175
|
+
profile: string | undefined,
|
|
176
|
+
experiment: OpenedExperimentRun["manifest"],
|
|
177
|
+
): PairedEffect => {
|
|
178
|
+
const scope = (entry: ExperimentEvaluation): boolean =>
|
|
179
|
+
entry.profileId === profile && entry.split === constraint.split;
|
|
180
|
+
return pairedEffect(
|
|
181
|
+
candidateEvaluations(experiment, "baseline").find(scope),
|
|
182
|
+
candidateEvaluations(experiment, candidate.id).find(scope),
|
|
183
|
+
constraint.metric,
|
|
184
|
+
constraint.confidence,
|
|
185
|
+
);
|
|
186
|
+
};
|
|
187
|
+
|
|
159
188
|
const normalizedConstraintViolation = (
|
|
160
189
|
campaign: ExperimentCampaign,
|
|
161
190
|
candidate: ExperimentDecisionCandidate,
|
|
162
191
|
constraint: ExperimentConstraint,
|
|
163
192
|
experiment: OpenedExperimentRun["manifest"],
|
|
164
193
|
): number => {
|
|
194
|
+
if (constraint.relativeTo && candidate.id === "baseline") return 0;
|
|
165
195
|
let profiles: Array<string | undefined> = campaign.profiles;
|
|
166
196
|
if (constraint.metric === "subject.bytes" || constraint.profile) {
|
|
167
197
|
profiles = [constraint.profile];
|
|
@@ -177,6 +207,18 @@ const normalizedConstraintViolation = (
|
|
|
177
207
|
);
|
|
178
208
|
let worst = 0;
|
|
179
209
|
for (const profile of profiles) {
|
|
210
|
+
if (constraint.relativeTo) {
|
|
211
|
+
const effect = relativeConstraintEffect(candidate, constraint, profile, experiment);
|
|
212
|
+
if (effect.note || effect.meanDelta === null) return Number.POSITIVE_INFINITY;
|
|
213
|
+
worst = Math.max(
|
|
214
|
+
worst,
|
|
215
|
+
violation(
|
|
216
|
+
effect.interval?.lower ?? effect.meanDelta,
|
|
217
|
+
effect.interval?.upper ?? effect.meanDelta,
|
|
218
|
+
),
|
|
219
|
+
);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
180
222
|
if (constraint.confidence) {
|
|
181
223
|
const groups = metricSampleGroups(
|
|
182
224
|
candidate,
|
|
@@ -189,6 +231,7 @@ const normalizedConstraintViolation = (
|
|
|
189
231
|
for (const samples of groups) {
|
|
190
232
|
try {
|
|
191
233
|
const interval = bootstrapMeanConfidenceInterval(samples, constraint.confidence);
|
|
234
|
+
if (confidenceGateIssue(interval)) return Number.POSITIVE_INFINITY;
|
|
192
235
|
worst = Math.max(worst, violation(interval.lower, interval.upper));
|
|
193
236
|
} catch {
|
|
194
237
|
return Number.POSITIVE_INFINITY;
|
|
@@ -209,13 +252,65 @@ const normalizedConstraintViolation = (
|
|
|
209
252
|
return worst;
|
|
210
253
|
};
|
|
211
254
|
|
|
255
|
+
const hasScoreEvidence = (
|
|
256
|
+
experiment: OpenedExperimentRun["manifest"],
|
|
257
|
+
split: ExperimentSplit,
|
|
258
|
+
): boolean =>
|
|
259
|
+
[...new Set(experiment.evaluations.map((entry) => entry.candidateId))]
|
|
260
|
+
.flatMap((id) => candidateEvaluations(experiment, id))
|
|
261
|
+
.some(
|
|
262
|
+
(entry) =>
|
|
263
|
+
entry.split === split &&
|
|
264
|
+
(entry.metricDefinitions?.score !== undefined ||
|
|
265
|
+
entry.metrics.score !== undefined ||
|
|
266
|
+
Object.values(entry.caseSamples ?? {}).some(
|
|
267
|
+
(sample) => sample.metrics.score !== undefined,
|
|
268
|
+
)),
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
const completeScoreEvidence = (entry: ExperimentEvaluation): boolean =>
|
|
272
|
+
entry.metrics.score !== undefined &&
|
|
273
|
+
(!entry.caseSamples ||
|
|
274
|
+
Object.keys(entry.casePassRates).every((id) => {
|
|
275
|
+
const sample = entry.caseSamples?.[id];
|
|
276
|
+
return sample?.metrics.score?.n === entry.repetitions && Boolean(sample.scoreBasis);
|
|
277
|
+
}));
|
|
278
|
+
|
|
279
|
+
const comparableScoreBasis = (
|
|
280
|
+
entry: ExperimentEvaluation,
|
|
281
|
+
reference: ExperimentEvaluation | undefined,
|
|
282
|
+
): boolean => {
|
|
283
|
+
if (!reference || !completeScoreEvidence(reference)) return false;
|
|
284
|
+
if (!entry.caseSamples || !reference.caseSamples)
|
|
285
|
+
return !entry.caseSamples && !reference.caseSamples;
|
|
286
|
+
const ids = new Set([
|
|
287
|
+
...Object.keys(entry.casePassRates),
|
|
288
|
+
...Object.keys(reference.casePassRates),
|
|
289
|
+
]);
|
|
290
|
+
return [...ids].every((id) => {
|
|
291
|
+
const basis = entry.caseSamples?.[id]?.scoreBasis;
|
|
292
|
+
return Boolean(basis) && basis === reference.caseSamples?.[id]?.scoreBasis;
|
|
293
|
+
});
|
|
294
|
+
};
|
|
295
|
+
|
|
212
296
|
export const rankCandidates = <T extends ExperimentDecisionCandidate>(
|
|
213
297
|
campaign: ExperimentCampaign,
|
|
214
298
|
candidates: readonly T[],
|
|
215
299
|
experiment: OpenedExperimentRun["manifest"],
|
|
216
300
|
constraintSplits: readonly ExperimentSplit[] = ["train", "validation", "test"],
|
|
217
|
-
): T[] =>
|
|
218
|
-
|
|
301
|
+
): T[] => {
|
|
302
|
+
const validationEvaluations = (id: string): ExperimentEvaluation[] =>
|
|
303
|
+
candidateEvaluations(experiment, id).filter((entry) => entry.split === "validation");
|
|
304
|
+
const referenceId = ["baseline", ...candidates.map((candidate) => candidate.id).sort()].find(
|
|
305
|
+
(id) => {
|
|
306
|
+
const entries = validationEvaluations(id);
|
|
307
|
+
return campaign.profiles.every((profile) =>
|
|
308
|
+
entries.some((entry) => entry.profileId === profile && completeScoreEvidence(entry)),
|
|
309
|
+
);
|
|
310
|
+
},
|
|
311
|
+
);
|
|
312
|
+
const reference = referenceId ? validationEvaluations(referenceId) : [];
|
|
313
|
+
return [...candidates].sort((a, b) => {
|
|
219
314
|
const activeConstraints = campaign.objectives.constraints.filter((constraint) =>
|
|
220
315
|
constraintSplits.includes(constraint.split),
|
|
221
316
|
);
|
|
@@ -267,20 +362,40 @@ export const rankCandidates = <T extends ExperimentDecisionCandidate>(
|
|
|
267
362
|
}
|
|
268
363
|
}
|
|
269
364
|
const quality = (candidate: ExperimentDecisionCandidate): number => {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
365
|
+
if (!hasScoreEvidence(experiment, "validation")) {
|
|
366
|
+
const values = metricValues(
|
|
367
|
+
candidate,
|
|
368
|
+
"quality.passRate",
|
|
369
|
+
undefined,
|
|
370
|
+
"validation",
|
|
371
|
+
experiment,
|
|
372
|
+
);
|
|
373
|
+
return values.length > 0 ? Math.min(...values) : -1;
|
|
374
|
+
}
|
|
375
|
+
const evaluations = candidateEvaluations(experiment, candidate.id);
|
|
376
|
+
const scores = campaign.profiles.map((profile) => {
|
|
377
|
+
const entry = evaluations.find(
|
|
378
|
+
(value) => value.profileId === profile && value.split === "validation",
|
|
379
|
+
);
|
|
380
|
+
if (
|
|
381
|
+
!entry ||
|
|
382
|
+
!completeScoreEvidence(entry) ||
|
|
383
|
+
!comparableScoreBasis(
|
|
384
|
+
entry,
|
|
385
|
+
reference.find((value) => value.profileId === profile),
|
|
386
|
+
)
|
|
387
|
+
)
|
|
388
|
+
return -1;
|
|
389
|
+
return entry.metrics.score ?? -1;
|
|
390
|
+
});
|
|
391
|
+
return scores.length > 0 ? Math.min(...scores) : -1;
|
|
278
392
|
};
|
|
279
393
|
const qualityDelta = quality(b) - quality(a);
|
|
280
394
|
if (qualityDelta !== 0) return qualityDelta;
|
|
281
395
|
if (a.sourceBytes !== b.sourceBytes) return a.sourceBytes - b.sourceBytes;
|
|
282
396
|
return a.id.localeCompare(b.id);
|
|
283
397
|
});
|
|
398
|
+
};
|
|
284
399
|
|
|
285
400
|
const candidateCaseVector = (
|
|
286
401
|
candidate: Candidate,
|
|
@@ -295,10 +410,15 @@ const candidateCaseVector = (
|
|
|
295
410
|
evaluations
|
|
296
411
|
.filter((entry) => entry.split === split)
|
|
297
412
|
.flatMap((entry) =>
|
|
298
|
-
Object.entries(entry.casePassRates).
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
413
|
+
Object.entries(entry.casePassRates).flatMap(([caseId, passRate]) => {
|
|
414
|
+
if (!hasScoreEvidence(experiment, split))
|
|
415
|
+
return [[`${entry.profileId}:${caseId}`, passRate]];
|
|
416
|
+
const sample = entry.caseSamples?.[caseId];
|
|
417
|
+
const score = sample?.metrics.score;
|
|
418
|
+
return score?.n === entry.repetitions && sample?.scoreBasis
|
|
419
|
+
? [[JSON.stringify([entry.profileId, caseId, sample.scoreBasis]), score.mean]]
|
|
420
|
+
: [];
|
|
421
|
+
}),
|
|
302
422
|
),
|
|
303
423
|
);
|
|
304
424
|
};
|
|
@@ -308,8 +428,9 @@ const dominates = (a: Record<string, number>, b: Record<string, number>): boolea
|
|
|
308
428
|
if (keys.size === 0) return false;
|
|
309
429
|
let strictlyBetter = false;
|
|
310
430
|
for (const key of keys) {
|
|
311
|
-
const av = a[key]
|
|
312
|
-
const bv = b[key]
|
|
431
|
+
const av = a[key];
|
|
432
|
+
const bv = b[key];
|
|
433
|
+
if (av === undefined || bv === undefined) return false;
|
|
313
434
|
if (av < bv) return false;
|
|
314
435
|
if (av > bv) strictlyBetter = true;
|
|
315
436
|
}
|
|
@@ -361,8 +482,13 @@ const frontierCoverage = (
|
|
|
361
482
|
const candidateVector = candidateCaseVector(candidate, experiment, "train");
|
|
362
483
|
const keys = new Set(vectors.flatMap((vector) => Object.keys(vector)));
|
|
363
484
|
return [...keys].filter((key) => {
|
|
364
|
-
const
|
|
365
|
-
|
|
485
|
+
const values = vectors.flatMap((vector) => (vector[key] === undefined ? [] : [vector[key]]));
|
|
486
|
+
const best = Math.max(...values);
|
|
487
|
+
return (
|
|
488
|
+
(frontier.length === 1 || values.length > 1) &&
|
|
489
|
+
candidateVector[key] !== undefined &&
|
|
490
|
+
candidateVector[key] === best
|
|
491
|
+
);
|
|
366
492
|
}).length;
|
|
367
493
|
};
|
|
368
494
|
|
|
@@ -379,6 +505,36 @@ export const searchFrontier = (
|
|
|
379
505
|
});
|
|
380
506
|
};
|
|
381
507
|
|
|
508
|
+
const relativeConstraintReport = (
|
|
509
|
+
campaign: ExperimentCampaign,
|
|
510
|
+
candidate: ExperimentDecisionCandidate,
|
|
511
|
+
constraint: ExperimentConstraint,
|
|
512
|
+
profile: string | undefined,
|
|
513
|
+
experiment: OpenedExperimentRun["manifest"],
|
|
514
|
+
): ExperimentSelection["constraints"][number] => {
|
|
515
|
+
const effect = relativeConstraintEffect(candidate, constraint, profile, experiment);
|
|
516
|
+
const reference = candidate.id === "baseline";
|
|
517
|
+
let values = effect.meanDelta === null ? [] : [effect.meanDelta];
|
|
518
|
+
if (reference) values = [0];
|
|
519
|
+
const note = reference ? "baseline reference; relative gate does not apply" : effect.note;
|
|
520
|
+
return {
|
|
521
|
+
candidateId: candidate.id,
|
|
522
|
+
metric: constraint.metric,
|
|
523
|
+
relativeTo: "baseline",
|
|
524
|
+
...(profile ? { profile } : {}),
|
|
525
|
+
split: constraint.split,
|
|
526
|
+
values,
|
|
527
|
+
passed: satisfiesConstraint(
|
|
528
|
+
campaign,
|
|
529
|
+
candidate,
|
|
530
|
+
{ ...constraint, ...(profile ? { profile } : {}) },
|
|
531
|
+
experiment,
|
|
532
|
+
),
|
|
533
|
+
...(!reference && effect.interval ? { interval: effect.interval } : {}),
|
|
534
|
+
...(note ? { note } : {}),
|
|
535
|
+
};
|
|
536
|
+
};
|
|
537
|
+
|
|
382
538
|
export const deriveExperimentSelection = (
|
|
383
539
|
campaign: ExperimentCampaign,
|
|
384
540
|
candidates: readonly ExperimentDecisionCandidate[],
|
|
@@ -405,6 +561,9 @@ export const deriveExperimentSelection = (
|
|
|
405
561
|
? [constraint.profile]
|
|
406
562
|
: campaign.profiles;
|
|
407
563
|
return profiles.map((profile) => {
|
|
564
|
+
if (constraint.relativeTo) {
|
|
565
|
+
return relativeConstraintReport(campaign, candidate, constraint, profile, experiment);
|
|
566
|
+
}
|
|
408
567
|
const values = metricValues(
|
|
409
568
|
candidate,
|
|
410
569
|
constraint.metric,
|
|
@@ -426,6 +585,7 @@ export const deriveExperimentSelection = (
|
|
|
426
585
|
if (samples) {
|
|
427
586
|
try {
|
|
428
587
|
interval = bootstrapMeanConfidenceInterval(samples, constraint.confidence);
|
|
588
|
+
note = confidenceGateIssue(interval);
|
|
429
589
|
} catch (error) {
|
|
430
590
|
note = error instanceof Error ? error.message : String(error);
|
|
431
591
|
}
|